轉:NSString何時用copy,何時用strong

大部分的時候NSString的屬性都是copy,那copy與strong的狀況下到底有什麼區別呢?安全

 

好比:app

@property (retain,nonatomic) NSString *rStr;atom

@property (copy, nonatomic)   NSString *cStr;指針

- (void)test:orm

{對象

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

    self.rStr   = mStr;字符串

    self.cStr     = mStr;string

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

    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對象根本就不能改變自身的值,他是不可變的。

 

把一個對象賦值給一個屬性變量,當這個對象變化了,若是但願屬性變量變化就使用strong屬性,若是但願屬性變量不跟着變化,就是用copy屬性。

 

由此能夠看出:

對源頭是NSMutableString的字符串,retain僅僅是指針引用,增長了引用計數器,這樣源頭改變的時候,用這種retain方式聲明的變量(不管被賦值的變量是可變的仍是不可變的),它也會跟着改變;而copy聲明的變量,它不會跟着源頭改變,它其實是深拷貝。

對源頭是NSString的字符串,不管是retain聲明的變量仍是copy聲明的變量,當第二次源頭的字符串從新指向其它的地方的時候,它仍是指向原來的最初的那個位置,也就是說其實兩者都是指針引用,也就是淺拷貝。

另外說明一下,這二者對內存計數的影響都是同樣的,都會增長內存引用計數,都須要在最後的時候作處理。

其實說白了,對字符串爲啥要用這兩種方式?我以爲仍是一個安全問題,好比聲明的一個NSString *str變量,而後把一個NSMutableString *mStr變量的賦值給它了,若是要求str跟着mStr變化,那麼就用retain;若是str不能跟着mStr一塊兒變化,那就用copy。而對於要把NSString類型的字符串賦值給str,那兩都沒啥區別。不會影響安全性,內存管理也同樣。

相關文章
相關標籤/搜索