一、問題來源 一直沒有搞清楚NSString、NSArray、NSDictionary……屬性描述關鍵字copy和strong的區別,看別人的項目中屬性定義有的用copy,有的用strong。自己在開發中也是沒有認真的去研究,至於使用copy還是用strong完全是根據心情隨性而為,也一直沒有出什麼 ...
一、問題來源
一直沒有搞清楚NSString、NSArray、NSDictionary……屬性描述關鍵字copy和strong的區別,看別人的項目中屬性定義有的用copy,有的用strong。自己在開發中也是沒有認真的去研究,至於使用copy還是用strong完全是根據心情隨性而為,也一直沒有出什麼問題。可蘋果竟然分了兩個關鍵字,就肯定有其用意,為了提高自己還是要仔細的搞清楚其中之差別!好了,廢話說完進入正題。
二、對象屬性描述copy與strong的區別
直接上代碼:
```
@property(nonatomic,strong) NSString strongImmutableString;
@property(nonatomic,copy) NSString copyImmutableString;
NSMutableString *mutableStr = [NSMutableString stringWithString:@"BUSYLIFE"];
self.immutableStrongStr = mutableStr;
self.immutableCopyStr = mutableStr;
NSLog(@"StrongStr:%@",_immutableStrongStr);
NSLog(@"CopyStr:%@",_immutableCopyStr);
[mutableStr appendString:@"1987"];
NSLog(@"mutableStr:%@",mutableStr);
NSLog(@"ChangedStrongStr:%@",_immutableStrongStr);
NSLog(@"ChangedCopyStr:%@",_immutableCopyStr);
NSLog(@"StrongStrAddress:%p",_immutableStrongStr);
NSLog(@"CopyStrAddress:%p",_immutableCopyStr);
NSLog(@"mutableStrAddress:%p",mutableStr);
```
結果如下:
上面代碼中我們將字元串屬性指向可變的字元串,當改變可變對象內容時,strong描述的屬性會跟著改變,copy描述的屬性則不會,從列印結果中可以看到strongImmutableString和可變對象mutableStr的地址是一樣的,而copyImmutableStr不是。
結論
為什麼我們在用@property聲明NSString是經常要使用copy而不是strong的原因
父類指針可以指向子類對象(如上代碼中NSMutableString是NSString的子類),使用copy的目的是為了對象有更好的封裝性,不受外部影響。無論外部傳入可變或不可變對象,本身持有一個不可變的副本。
使用strong,屬性可能指向可變對象,如果這個對象被外部更改,則該屬性也會受到影響。
同樣和NSString有可變子類的NSArray,NSDictionary,在聲明時也應該使用copy描述。
三、對象的copy與mutablecopy
要更好的理解,我們需要搞清楚下麵兩種情況:
非集合對象的copy與mutablecopy
集合對象的copy與mutablecopy
在非集合類對象中:對 immutable(不可變) 對象進行 copy 操作,是指針複製,mutableCopy 操作時內容複製;對 mutable(可變) 對象進行 copy 和 mutableCopy 都是內容複製。用代碼簡單表示如下:
- [immutableObject copy] // 淺複製
- [immutableObject mutableCopy] //深複製
- [mutableObject copy] //深複製
- [mutableObject mutableCopy] //深複製
集合類對象是指 NSArray、NSDictionary、NSSet ... 之類的對象。下麵先看集合類immutable對象使用 copy 和 mutableCopy 的一個例子:
NSArray *array = @[@"a", @"b"];
NSArray *copyArray = [array copy];
NSMutableArray *mCopyArray = [array mutableCopy];
查看內容,可以看到 copyArray 和 array 的地址是一樣的,而 mCopyArray 和 array 的地址是不同的。說明 copy 操作進行了指針拷貝,mutableCopy 進行了內容拷貝。但需要強調的是:此處的內容拷貝,僅僅是拷貝 array 這個對象,array 集合內部的元素仍然是指針拷貝。
- [immutableObject copy] // 淺複製
- [immutableObject mutableCopy] //單層深複製
- [mutableObject copy] //單層深複製
- [mutableObject mutableCopy] //單層深複製
理解了這兩種操作,就可以很容易的明白上面property聲明NSString時用copy到底發生了什麼以及他的作用了。
本文若有不對之處,歡迎大家拍磚!