ios 自動內存管理 ARC

原文出自:http://my.oschina.net/u/811205/blog/176651


今天在公司爆出一個 BUG,導致5000+crash. 

大致是 UIKit 中的 delegate 訪問了已經釋放了的界面,也就是使用了野指針導致 crash. 

回來演示了一下發現 

?
1
2
@property (nonatomic, assign) id<MyCellDelegate> delegate;//1
@property (nonatomic, weak) id<MyCellDelegate> delegate;//2
大部分的 UIKit 的 delegate 都是如1的聲明 

因爲 ios 在5之前是沒有 ARC 的,爲了兼容所以寫的都是 assign 

那麼 assign 與 weak 有什麼區別呢? 

?
1
2
3
4
5
__strong NSString *yourString = [[NSString alloc] initWithUTF8String:"your string"];
__weak  NSString *myString = yourString;  
yourString = nil;  
__unsafe_unretained NSString *theirString = myString; 
//現在所有的指針都爲nil
weak的特性,如果指向的內存被釋放了,則自動指向 nil; 

所以使用 weak 是不會有野指針的

而 assign 和unsafe_unretained,永遠指向某內存地址,如果該內存被釋放了,自己就會成爲野指針

如下

?
1
2
3
4
5
__strong NSString *yourString = @"Your String";  
__weak  NSString *myString = yourString;  
__unsafe_unretained NSString *theirString = myString; 
yourString = nil;  
//現在yourString與myString的指針都爲nil,而theirString不爲nil,但是是野指針。
所以我們在使用 UIKit 中的 delegate 的時候,要避免響應 delegate 的VC,或者 View 之類的實例被提前釋放了,而導致 crash 

而我們自己的 delegate 可以直接寫成 weak 的,既避免了循環引用,又不會產生野指針.

PS:assign 只能用在屬性的定義,變量的定義就可以用類似的 unsafe_unretained

that`s all...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章