1.因?yàn)楦割愔羔樋梢灾赶蜃宇悓?duì)象,使用 copy 的目的是為了讓本對(duì)象的屬性不受外界影響,使用 copy 無論給我傳入是一個(gè)可變對(duì)象還是不可對(duì)象,我本身持有的就是一個(gè)不可變的副本.
2.如果我們使用是 strong ,那么這個(gè)屬性就有可能指向一個(gè)可變對(duì)象,如果這個(gè)可變對(duì)象在外部被修改了,那么會(huì)影響該屬性.
copy 此特質(zhì)所表達(dá)的所屬關(guān)系與 strong 類似馏臭。然而設(shè)置方法并不保留新值梢夯,而是將其“拷貝” (copy)。 當(dāng)屬性類型為 NSString 時(shí),經(jīng)常用此特質(zhì)來保護(hù)其封裝性,因?yàn)閭鬟f給設(shè)置方法的新值有可能指向一個(gè) NSMutableString 類的實(shí)例。這個(gè)類是 NSString 的子類,表示一種可修改其值的字符串几睛,此時(shí)若是不拷貝字符串,那么設(shè)置完屬性之后粤攒,字符串的值就可能會(huì)在對(duì)象不知情的情況下遭人更改所森。所以,這時(shí)就要拷貝一份“不可變” (immutable)的字符串夯接,確保對(duì)象中的字符串值不會(huì)無意間變動(dòng)焕济。只要實(shí)現(xiàn)屬性所用的對(duì)象是“可變的” (mutable),就應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份盔几。
舉例說明:
定義一個(gè)以 strong 修飾的 array:
@property (nonatomic ,readwrite, strong)NSArray*array;
然后進(jìn)行下面的操作:
NSMutableArray*mutableArray = [[NSMutableArray alloc] init];
self.array = @[ @1, @2, @3, @4];? ??
self.array = mutableArray;? ?
?[mutableArray removeAllObjects];
NSLog(@"%@",self.array);? ??
[mutableArray addObjectsFromArray:array];? ?
?self.array = [mutableArray copy];? ?
?[mutableArray removeAllObjects];
NSLog(@"%@",self.array);
打印結(jié)果如下所示:
2015-09-2719:10:32.523CYLArrayCopyDmo[10681:713670] ()
2015-09-2719:10:32.524CYLArrayCopyDmo[10681:713670]
(1,
2,
3,
4)
為了理解這種做法晴弃,首先要知道,兩種情況:
對(duì)非集合類對(duì)象的 copy 與 mutableCopy 操作逊拍;
對(duì)集合類對(duì)象的 copy 與 mutableCopy 操作上鞠。
在非集合類對(duì)象中:對(duì) immutable 對(duì)象進(jìn)行 copy 操作,是指針復(fù)制芯丧,mutableCopy 操作時(shí)內(nèi)容復(fù)制芍阎;對(duì) mutable 對(duì)象進(jìn)行 copy 和 mutableCopy 都是內(nèi)容復(fù)制。用代碼簡單表示如下:
[immutableObject copy] // 淺復(fù)制
[immutableObject mutableCopy] //深復(fù)制
[mutableObject copy] //深復(fù)制
[mutableObject mutableCopy] //深復(fù)制
比如以下代碼:
NSMutableString*string = [NSMutableString ?stringWithString:@"origin"];//copy
NSString*stringCopy = [string copy];
查看內(nèi)存注整,會(huì)發(fā)現(xiàn) string能曾、stringCopy 內(nèi)存地址都不一樣度硝,說明此時(shí)都是做內(nèi)容拷貝肿轨、深拷貝。即使你進(jìn)行如下操作:
[string appendString:@"origion!"]
stringCopy 的值也不會(huì)因此改變蕊程,但是如果不使用 copy椒袍,stringCopy 的值就會(huì)被改變。 集合類對(duì)象以此類推藻茂。 所以驹暑,
用 @property 聲明 NSString、NSArray辨赐、NSDictionary 經(jīng)常使用 copy 關(guān)鍵字优俘,是因?yàn)樗麄冇袑?duì)應(yīng)的可變類型:NSMutableString、NSMutableArray掀序、NSMutableDictionary帆焕,他們之間可能進(jìn)行賦值操作,為確保對(duì)象中的字符串值不會(huì)無意間變動(dòng)不恭,應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份叶雹。
2财饥、集合類對(duì)象的copy與mutableCopy
集合類對(duì)象是指 NSArray、NSDictionary折晦、NSSet ... 之類的對(duì)象钥星。下面先看集合類immutable對(duì)象使用 copy 和 mutableCopy 的一個(gè)例子:
NSArray*array = @[@[@"a",@"b"], @[@"c",@"d"]];
NSArray*copyArray = [array copy];
NSMutableArray*mCopyArray = [array mutableCopy];
查看內(nèi)容,可以看到 copyArray 和 array 的地址是一樣的满着,而 mCopyArray 和 array 的地址是不同的谦炒。說明 copy 操作進(jìn)行了指針拷貝,mutableCopy 進(jìn)行了內(nèi)容拷貝漓滔。但需要強(qiáng)調(diào)的是:此處的內(nèi)容拷貝编饺,僅僅是拷貝 array 這個(gè)對(duì)象,array 集合內(nèi)部的元素仍然是指針拷貝响驴。這和上面的非集合 immutable 對(duì)象的拷貝還是挺相似的透且,那么mutable對(duì)象的拷貝會(huì)不會(huì)類似呢?我們繼續(xù)往下豁鲤,看 mutable 對(duì)象拷貝的例子:
NSMutableArray*array = [NSMutableArray ?arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray*copyArray = [array copy];
NSMutableArray*mCopyArray = [arraymutable Copy];
查看內(nèi)存秽誊,如我們所料,copyArray琳骡、mCopyArray和 array 的內(nèi)存地址都不一樣锅论,說明 copyArray、mCopyArray 都對(duì) array 進(jìn)行了內(nèi)容拷貝楣号。同樣最易,我們可以得出結(jié)論:
在集合類對(duì)象中,對(duì) immutable 對(duì)象進(jìn)行 copy炫狱,是指針復(fù)制藻懒, mutableCopy 是內(nèi)容復(fù)制;對(duì) mutable 對(duì)象進(jìn)行 copy 和 mutableCopy 都是內(nèi)容復(fù)制视译。但是:集合對(duì)象的內(nèi)容復(fù)制僅限于對(duì)象本身嬉荆,對(duì)象元素仍然是指針復(fù)制。用代碼簡單表示如下:
[immutableObject ?copy]// 淺復(fù)制[immutableObject ?mutableCopy]//單層深復(fù)制[mutableObject ?copy]//單層深復(fù)制[mutableObject ?mutableCopy]//單層深復(fù)制
這個(gè)代碼結(jié)論和非集合類的非常相似酷含。