求一个看准网账号密码的账号密码

ARC与非ARC下的Weak-Strong&Dance_阮涛_新浪博客
ARC与非ARC下的Weak-Strong&Dance
在使用block过程中,经常会遇到retain cycle的问题,例如:
[cpp] view
-&(void)dealloc&&
&&[[NSNotificationCenter&defaultCenter]&removeObserver:_observer];&&
-&(void)loadView&&
&&[super&loadView];&&
&&_observer&=&[[NSNotificationCenter&defaultCenter]&addObserverForName:@"testKey"
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&object:nil&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&queue:nil&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&usingBlock:^(NSNotification&*note)&{&&
&&&&&&[self&dismissModalViewControllerAnimated:YES];&&&&
在block中用到了self,self会被block
retain,而_observer会copy一份该block,就是说_observer间接持有self,同时当前的self也会retain
_observer,最终导致self持有_observer,_observer持有self,形成retain
cycle。对于在block中的retain cycle,在2011 WWDC Session #322 (Objective-C
Advancements in Depth)有一个解决方案weak-strong
dance,很漂亮的名字。其实现如下:
view plaincopy
-&(void)dealloc&&
&&[[NSNotificationCenter&defaultCenter]&removeObserver:_observer];&&
-&(void)loadView&&
&&[super&loadView];&&
&&__weak&TestViewController&*wself&=&&&
&&_observer&=&[[NSNotificationCenter&defaultCenter]&addObserverForName:@"testKey"
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&object:nil&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&queue:nil&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&usingBlock:^(NSNotification&*note)&{&&
&&&&&&TestViewController&*sself&=&&&
&&&&&&[sself&dismissModalViewControllerAnimated:YES];&&
在block中使用self之前先用一个__weak变量引用self,导致block不会retain
self,打破retain
cycle,然后在block中使用wself之前先用__strong类型变量引用wself,以确保使用过程中不会dealloc。简而言之就是推迟对self的retain,在使用时才进行retain。这有点像lazy
loading的意思。注:iOS5以下没有__weak,则需使用__unsafe_unretained。
在非ARC环境中,显然之前的使用的__weak或__unsafe_unretained将会是无效的,那么我们需使用另外一种方法来代替,这里就需要用到__block。
__block在ARC和非ARC中有点细微的差别(Automatic Reference
Counting : Blocks
在ARC中,__block会自动进行retain
在非ARC中,__block不会自动进行retain
因此首先要注意的一点就是用__block打破retain
cycle的方法仅在非ARC下有效,下面是非ARC的weak-strong dance:
view plaincopy
-&(void)dealloc&&
&&[[NSNotificationCenter&defaultCenter]&removeObserver:_observer];&&
&&[_observer&release];&&
&&[super&dealloc];&&
-&(void)loadView&&
&&[super&loadView];&&
&&__block&TestViewController&*bself&=&&&
&&_observer&=&[[NSNotificationCenter&defaultCenter]&addObserverForName:@"testKey"
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&object:nil&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&queue:nil&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&ngBlock:^(NSNotification&*note)&{&&
&&&&&&[bself&retain];&&
&&&&&&[bself&dismissModalViewControllerAnimated:YES];&&
&&&&&&[bself&release];&&
将self赋值为__block类型变量,在非ARC中__block类型变量不会进行retain,从而打破retain
cycle,然后在使用bself前进行retain,以确保在使用过程中不会dealloc
转自/bbs/read.php?tid=221091
博客等级:
博客积分:0
博客访问:30,968
关注人气:0
荣誉徽章:也许我们在学习的时候,有人会告诉我们,UI控件的属性用weak修饰,而且,从Storyboard中拖出来的控件也都是用weak来修饰的,所以在习惯上,我们总会用weak去修饰。然而,在某些情况下,这么做是会出问题的,这时我们必须用strong来修饰。
探讨之前,首先要了解Objective C的内存管理机制,即引用计数。
一个对象何时会被释放呢?答案是,当引用计数为0的时候。
建立一个UIView,声明一个控件属性,用weak修饰
@property (nonatomic, weak) UIView *aV
那么我们将分两种情况来进行测试。
一、在viewDidLoad中初始化这个控件。
可以看到编译器已经给出警告了,当这行代码执行完,这个UIView就会被释放掉了。
接下来我们换一种写法
此时编译器已经不会报错了,但是这么写是有问题的,当出了最下面这个大括号之后,这个对象也将不复存在。也会变成nil.
或者懒加载
诶,我们平时就是这么写的。那么为什么这么写这个视图就不会消失了呢?而且在别的方法中再访问self.aView也是有值的呢。
我们进到系统的UIView.h头文件中,可以看到这个属性。当我们执行了addSubview:方法之后,后面的视图就会被放到这个数组里。
可以看到,这个数组使用copy修饰的,也就是说,这是强引用!正是这个原因,我们才能用weak来修饰一个控件。因此可以保持这个控件的引用计数不为0,就不会被释放掉了。
那么我们在开发中,到底是用weak还是用strong?
1、如果你真的怕麻烦,也不想理解什么内存管理,你就用strong就对了。
2、可以分情况来看,如果你用strong修饰了属性,并且也addSubview:了,虽然引用计数为2,但是当整个父视图被销毁的时候,这两个引用计数都会变成0,所以不会造成内存泄漏。
3、具体的情况就是,我们有时候在一个视图1中,需求要求我们声明一个视图2,这个视图2不一定是视图1的子视图,此时假如视图2有值:那么weak时,引用计数为0,这个视图相当于不存在。strong时,引用计数为1,不管你添加不添加到视图1的子视图,视图2都存在。简要概括:
视图2有值的情况下,如何保证它不会消失?其实就是保证它不被释放。
weak:视图1存在,视图2不一定存在。取决于视图2是否有强引用。
strong:视图1存在,视图2就存在。因为strong会使引用计数+1.
可以参考另一篇文章:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2819次
排名:千里之外提示:本文中所说的""即是"成员变量","局部变量"即是"本地变量"
ARC是自 5之后增加的新特性,完全消除了手动管理的烦琐,编译器会自动在适当的地方插入适当的retain、release、autorelease语句。你不再需要担心内存管理,因为编译器为你处理了一切
注意:ARC 是编译器特性,而不是 iOS 运行时特性(除了weak指针系统),它也不是类似于其它语言中的垃圾收集器。因此 ARC 和手动内存管理性能是一样的,有时还能更加快速,因为编译器还可以执行某些优化
ARC 的规则非常简单:只要还有一个变量指向对象,对象就会保持在内存中。当指针指向新值,或者指针不再存在时,相关联的对象就会自动释放。这条规则对于实例变量、synthesize属性、局部变量都是适用的
三、strong指针
控制器中有个文本输入框框属性
@property&(nonatomic,&assign)&IBOutlet&UITextField&*nameF&&
1.如果用户在文本框中输入mj这个字符串
那么就可以说,nameField的text属性是NSString对象的指针,也就是拥有者,该对象保存了文本输入框的内容
2.如果执行了如下代码
NSString&*name&=&self.nameField.&&
一个对象可以有多个拥有者,在上面代码中,name变量同样也是这个NSString对象的拥有者,也就是有两个指针指向同一个对象
3.随后用户改变了输入框的内容,比如
此时nameFeild的text属性就指向了新的NSString对象。但原来的NSString对象仍然还有一个所有者(name变量),因此会继续保留在内存中
4.当name变量获得新值,或者不再存在时(如局部变量方法返回时、实例变量对象释放时),原先的NSString对象就不再拥有任何所有者,retain计数降为0,这时对象会被释放
如,给name变量赋予一个新值
name&=&@"Jake";&&
我们称name和nameField.text指针为"Strong指针",因为它们能够保持对象的生命。默认所有实例变量和局部变量都是Strong指针
四、weak指针
weak型的指针变量仍然可以指向一个对象,但不属于对象的拥有者
1.执行下面的代码
__weak&NSString&*name&=&self.nameField.&&
name变量和nameField.text属性都指向同一个NSString对象,但name不是拥有者
2.如果文本框的内容发生变化,则原先的NSString对象就没有拥有者,会被释放,此时name变量会自动变成nil,称为空指针
weak型的指针变量自动变为nil是非常方便的,这样阻止了weak指针继续指向已释放对象,避免了野指针的产生,不然会导致非常难于寻找的Bug,空指针消除了类似的问题
3.weak指针主要用于&父-子&关系,父亲拥有一个儿子的strong指针,因此父亲是儿子的所有者;但为了阻止所有权,儿子需要使用weak指针指向父亲。典型是delegate模式,你的ViewController通过strong指针(self.view)拥有一个UITableView,&UITableView的dataSource和delegate都是weak指针,指向你的ViewController
五、strong和weak指针的使用注意
1.下面代码是有问题的:
__weak&NSString&*str&=&[[NSString&alloc]&initWithFormat:@"1234"];&&
NSLog(@"%@",&str);&
str是个weak指针,所以NSString对象没有拥有者,在创建之后就会被立即释放。Xcode还会给出警告("Warning: Assigning retained obj object will be released after assignment")
2.一般的指针变量默认就是strong类型的,因此一般我们对于strong变量不加__strong修饰,以下两行代码是等价的:
NSString&*name&=&self.nameField.&&
__strong&NSString&*name&=&self.nameField.&&
3.属性可以是strong或weak,写法如下
@property&(nonatomic,&strong)&NSString&*&&
@property&(nonatomic,&weak)&id&&&
4.以下代码在ARC之前是可能会行不通的,因为在手动内存管理中,从NSArray中移除一个对象时,这个对象会发送一条release消息,可能会被立即释放。随后NSLog()打印该对象就会导致应用崩溃
id&obj&=&[array&objectAtIndex:0];&&
[array&removeObjectAtIndex:0];&&
NSLog(@"%@",&obj);&&
在ARC中这段代码是完全合法的,因为obj变量是一个strong指针,它成为了对象的拥有者,从NSArray中移除该对象也不会导致对象被释放
六、ARC小结
1.有了ARC,我们的代码可以清晰很多,你不再需要考虑什么时候retain或release对象。唯一需要考虑的是对象之间的关联,也就是哪个对象拥有哪个对象?
2.ARC也有一些:
1& 首先ARC只能工作于Objective-C对象,如果应用使用了Core 或malloc()/free(),此时还是需要你来手动管理内存
2& 此外ARC还有其它一些更为严格的语言规则,以确保ARC能够正常地工作
3.虽然ARC管理了retain和release,但并不表示你完全不需要关心内存管理的问题。因为strong指针会保持对象的生命,某些情况下你仍然需要手动设置这些指针为nil,否则可能导致应用内存不足。无论何时你创建一个新对象时,都需要考虑谁拥有该对象,以及这个对象需要存活多久
4.ARC还能很好地C++使用,这对游戏开发是非常有帮助的。对于iOS 4,ARC有一点点限制(不支持weak指针),但也没太大关系
七、ARC使用注意总结
1.不能直接调用dealloc方法,不能调用retain,release,autorelease,retainCount方法,包括@selector(retain)的方式也不行
2.可以用dealloc方法来管理一些资源,但不能用来释放实例变量,也不能在dealloc方法里面去掉[super dealloc]方法,在ARC下父类的dealloc同样由编译器来自动完成
3.Core Foundation类型的对象仍然可以用CFRetain,CFRelease这些方法
4.不能再使用NSAllocateObject和NSDeallocateObject对象
5.不能在C结构体中使用对象指针,如果有类似功能可以创建一个Objective-C类来管理这些对象
6.在id和void*之间没有简便的转换方法,同样在Objective-C和Core Foundation类型之间的转换都需要使用编译器制定的转换函数
7.不能再使用NSAutoreleasePool对象,ARC提供了@autoreleasepool块来代替它,这样更有效率
8.不能使用内存存储区(不能再使用NSZone)
9.不能以new为开头给一个属性命名
10.声明IBOutlet时一般应当使用weak,除了对StoryBoard这样nib中间的顶层对象要用strong
11.weak相当于老的assign,strong相当于retain

我要回帖

更多关于 求个学信网账号密码 的文章

 

随机推荐