屬性關(guān)鍵字:copy
copy的字面意思就是“復(fù)制”,它是產(chǎn)生一個(gè)副本的過程,再來看在iOS里,copy與mutableCopy都是NSObject里的方法,一個(gè)NSObject的對(duì)象要想使用這兩個(gè)函數(shù),那么類必須實(shí)現(xiàn)NSCopying協(xié)議或NSMutableCopying協(xié)議,并且是實(shí)現(xiàn)了一般來說我們用的很多系統(tǒng)里的容器類已經(jīng)實(shí)現(xiàn)了這些方法。
copy到底是深拷貝還是淺拷貝?
答:我相信有的同學(xué)認(rèn)為只要是使用copy關(guān)鍵字,那么肯定都是深拷貝,這樣是很不嚴(yán)謹(jǐn)?shù)?,就比如上個(gè)例子,雖然使用了copy,但是指針地址是一樣,那么它就應(yīng)該是淺拷貝。
所以是否是深淺拷貝,是否創(chuàng)建新的對(duì)象,是由程序運(yùn)行的環(huán)境所造成的,并不是一概而論。
深淺copy
淺copy:指針復(fù)制,不會(huì)創(chuàng)建一個(gè)新的對(duì)象。
深copy:內(nèi)容復(fù)制,會(huì)創(chuàng)建一個(gè)新的對(duì)象。
關(guān)于 NSString 與 NSMutableString 的例子
NSString *Str = [[NSString alloc]init];
NSString *Str2 = [Str copy];
NSLog(@"Str : %p",Str); //Str : 0x102e5b468 (Str對(duì)象地址)
NSLog(@"Str2 : %p",Str2); //Str2 : 0x102e5b468 (Str2對(duì)象地址)
可以看出,對(duì)于不可變對(duì)象的 NSString 使用copy是淺拷貝,因?yàn)閭z個(gè)對(duì)象地址相同,未開辟新的內(nèi)存空間。
NSMutableString *mStr = [[NSMutableString alloc]init];
NSMutableString *mStr2 = [mStr copy];
NSLog(@"mStr : %p",mStr); // mStr : 0x60000145d620 (mStr對(duì)象地址)
NSLog(@"mStr2 : %p",mStr2); // mStr2 : 0x103e3e7c8 (mStr2對(duì)象地址)
而對(duì)于NSMutableString可以看出,對(duì)于可變對(duì)象的 NSMutableString 使用copy是深拷貝,因?yàn)閭z個(gè)對(duì)象地址不同,開辟新的內(nèi)存空間。
蘋果為什么要這么設(shè)計(jì)?這么設(shè)計(jì)的優(yōu)點(diǎn)是什么?(為什么NSString使用copy是淺拷貝,而NSMutableString是深拷貝)
答:因?yàn)镹SString指的是一個(gè)不可變對(duì)象,所以如果使用copy的話也會(huì)復(fù)制一個(gè)不可變對(duì)象,但是這
時(shí)候其實(shí)復(fù)制的對(duì)象和原來的對(duì)象的內(nèi)存地址是一樣的,個(gè)人覺得這種設(shè)計(jì)方式是為了節(jié)省內(nèi)存空間,
因?yàn)镹SString指的是一個(gè)不可變對(duì)象,無論是copy前后的對(duì)象都是不可變的對(duì)象,所以新開鋪內(nèi)存空
間并沒有什么意義,這也可以解釋為什么 NSString * str1=@"a"; NSString *str2 =
[str1 copy]; str1 = @“b”,b 的內(nèi)存地址會(huì)變得原因。
而NSMutableString,使用copy會(huì)新開辟內(nèi)存空間的原因和上面想法,因?yàn)镹SMutableString
是一個(gè)可變對(duì)象,本身設(shè)計(jì)出來就是為了靈活變化用的。