關於retain,assign,copy,strong,weak的見解

如果有錯誤的地方,請指正。

首先這裏涉及到iOS的內存管理機制,大致來講就是有申請就必定要有釋放,在mrc狀態下,如果使用alloc init等創建對象,其對象內部的引用計數器就會加1,你就必須要進行一次release,然後系統會在dealloc中自動釋放。


assign--基礎數據類型,簡單賦值,引用計數器不變化。

retain--引用計數器加1,一般用於NSString和基礎數據類型以外的類對象創建,他的含義是淺拷貝,也就是拷貝對象指針,但不拷貝內部內容,指針所指內容是一致的。

copy--引用計數器加1,一般用於nsstring,指深拷貝,也就是拷貝對象的內容和指針,消除舊對象。

strong--arc機制下的強指針引用,引用計數器加1,他的含義約等於retain。

weak-arc機制下的弱指針,所有指向這個對象的weak指針都將被置爲nil,能避免因爲意外釋放而導致的carsh。

那麼在一般聲明控件時,假若是ib控件,則默認爲weak狀態,如果非ib狀態下進行聲明,則具體代碼如下

@interface AController : UIViewController


{


    __weak UIView *aView;


}



@end




@implementation AController


- (void) viewDidLoad


{


    [super viewDidLoad];


    


    UIView *view = [[UIView alloc]initWithFrame:CGRectZero];


    [self.view addSubview:view];


    aView = view;


}



@end


基本還用weak聲明,因爲Controller並不直接“擁有”控件,控件由它的父view“擁有”。使用weak關鍵字可以不增加控件引用計數,確保控件與父view有相同的生命週期。

控件在被addSubview後,相當於控件引用計數+1;父view銷燬後,所有的子view引用計數-1,則可以確保父view銷燬時子view立即銷燬。weak的控件在removeFromSuperview後也會立即銷燬,而strong的控件不會,因爲Controller還保有控件強引用。

在控件addSubview後再對weak變量賦值,防止控件被立即釋放。



下面再來個例子,比如爲什麼NSString一般用copy而不用retain或者strong。
例子是摘抄別人的,懶得再打

@property (retain,nonatomicNSString *rStr;

@property (copynonatomic)   NSString *cStr;

- (void)test:

{

    NSMutableString *mStr = [NSMutableStringstringWithFormat:@"abc"];

    self.rStr   = mStr;

    self.cStr     = mStr;

    NSLog(@"mStr:%p,%p",  mStr,&mStr);

    NSLog(@"retainStr:%p,%p"_rStr, &_rStr);

    NSLog(@"copyStr:%p,%p",   _cStr, &_cStr);

假如,mStr對象的地址爲0x11,也就是0x11是@“abc”的首地址,mStr變量自身在內存中的地址爲0x123;

當把mStr賦值給retain的rStr時,rStr對象的地址爲0x11,rStr變量自身在內存中的地址爲0x124;rStr與mStr指向同樣的地址,他們指向的是同一個對象@“abc”,這個對象的地址爲0x11,所以他們的值是一樣的。

當把mStr賦值給copy的cStr時,cStr對象的地址爲0x22,cStr變量自身在內存中的地址0x125;cStr與mStr指向的地址是不一樣的,他們指向的是不同的對象,所以copy是深複製,一個新的對象,這個對象的地址爲0x22,值爲@“abc”。


如果現在改變mStr的值:

    [mStr appendString:@"de"];

    NSLog(@"retainStr:%@",  _rStr);

    NSLog(@"copyStr:%@",    _cStr);


結果,

使用retain的字串rStr的值:@"abcde",

而使用copy的字串cStr的值:@"abc",

所以,如果一般情況下,我們都不希望字串的值跟着mStr變化,所以我們一般用copy來設置string的屬性。

如果希望字串的值跟着賦值的字串的值變化,可以使用strong,retain。

注意:上面的情況是針對於當把NSMutableString賦值給NSString的時候,纔會有不同,如果是賦值是NSString對象,那麼使用copy還是strong,結果都是一樣的,因爲NSString對象根本就不能改變自身的值,他是不可變的。


所以總的來說,NSString本身是無所謂的,但是如果一個 NSString 指針指向了一個 NSMutableString的內存空間的話,如果使用 strong 修飾的話,如果你在別處修改這個值的話,那麼原來的值也會改變。用 copy 是生成了一份新的內存空間,原值不會改變,所以一般使用copy就足夠了,因爲我們很少有需求能跟隨字符串變化而變化的字符串。



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