iOS原始碼(二)copy的理解
屬性關鍵字:copy
copy的字面意思就是“複製”,它是產生一個副本的過程,再來看在iOS裡,copy與mutableCopy都是NSObject裡的方法,一個NSObject的物件要想使用這兩個函式,那麼類必須實現NSCopying協議或NSMutableCopying協議,並且是實現了一般來說我們用的很多系統裡的容器類已經實現了這些方法。
copy到底是深拷貝還是淺拷貝?
答:我相信有的同學認為只要是使用copy關鍵字,那麼肯定都是深拷貝,這樣是很不嚴謹的,就比如上個例子,雖然使用了copy,但是指標地址是一樣,那麼它就應該是淺拷貝。
所以是否是深淺拷貝,是否建立新的物件,是由程式執行的環境所造成的,並不是一概而論。
深淺copy
淺copy:指標複製,不會建立一個新的物件。
深copy:內容複製,會建立一個新的物件。
關於 NSString 與 NSMutableString 的例子
NSString *Str = [[NSString alloc]init]; NSString *Str2 = [Str copy]; NSLog(@"Str :%p",Str);//Str :0x102e5b468(Str物件地址) NSLog(@"Str2 :%p",Str2);//Str2 :0x102e5b468(Str2物件地址)
可以看出,對於不可變物件的 NSString 使用copy是淺拷貝,因為倆個物件地址相同,未開闢新的記憶體空間。
NSMutableString *mStr = [[NSMutableString alloc]init]; NSMutableString *mStr2 = [mStr copy]; NSLog(@"mStr :%p",mStr);// mStr :0x60000145d620(mStr物件地址) NSLog(@"mStr2 :%p",mStr2);// mStr2 :0x103e3e7c8(mStr2物件地址)
而對於NSMutableString可以看出,對於可變物件的 NSMutableString 使用copy是深拷貝,因為倆個物件地址不同,開闢新的記憶體空間。
蘋果為什麼要這麼設計?這麼設計的優點是什麼?(為什麼NSString使用copy是淺拷貝,而NSMutableString是深拷貝)
答:因為NSString指的是一個不可變物件,所以如果使用copy的話也會複製一個不可變物件,但是這 時候其實複製的物件和原來的物件的記憶體地址是一樣的,個人覺得這種設計方式是為了節省記憶體空間, 因為NSString指的是一個不可變物件,無論是copy前後的物件都是不可變的物件,所以新開鋪記憶體空 間並沒有什麼意義,這也可以解釋為什麼 NSString* str1=@"a"; NSString *str2 = [str1 copy];str1 = @“b”,b 的記憶體地址會變得原因。 而NSMutableString,使用copy會新開闢記憶體空間的原因和上面想法,因為NSMutableString 是一個可變物件,本身設計出來就是為了靈活變化用的。