copy和mutableCopy
copy和mutableCopy
淺複製:不考慮物件本身,僅僅拷貝指向物件的指標
深複製:是直接拷貝整個物件記憶體到另一塊記憶體中
一般情況下,=
基本上都是淺複製:
UIView *view1 = [[UIView alloc] init];
UIView *view2 = [[UIView alloc] init];
view1 = view2;
view1
和view2
的記憶體地址是一樣的.
copy
字面意思就是複製.
copy
和mutableCopy
都是NSObject
的方法,一個NSObject
的物件想要使用這兩個方法,類必須實現NSCopying
NSMutableCopying
協議.如果不遵守協議,直接使用
[xxx copy]
,會直接導致程式崩潰.比如UIView
類
copy
關鍵字特點:
修改源物件的屬性和行為,不會影響副本物件
修改副本物件的屬性和行為,不會影響源物件
一個物件可以通過copy
或mutableCopy
方法來建立一個副本物件
copy
:建立的是不可變副本(NSString, NSArray, NSDictionary
)
mutableCopy
:建立的是可變副本(NSMutableString,NSMutableArray,NSMutableDictionary
)
原則: 修改新(舊)物件,不影響舊(新)物件!而且不一定產生新的物件!
NSString *str = @"str";
NSMutableString *strM = [str mutableCopy];
NSLog(@"%@, %p", str, str);
NSLog(@"%@, %p", strM, strM);
列印結果為:
str, 0x12345678
str, 0x12347890
內容一樣,地址變了.
修改新(舊)物件,不會影響舊(新)物件,所以生成一個新物件
以前物件是個不可變物件,通過mutableCopy
拷貝的必須是一個不可變物件,所以必須生成一個新物件
同理:
NSMutableString *strM = [NSMutableString stringWithFormat:@"strM"];
NSMutableString *str = [strM mutableCopy];
[str appendString:@"123"]
NSLog(@"%@, %p", strM, strM);
NSLog(@"%@, %p", str, str);
列印結果為:
strM, 0x1268312783
strM123, 0x1723009183
再同理:
NSMutableString *strM = [NSMutableString stringWithFormat:@"strM"];
NSString *str = [strM copy];
NSLog(@"%@, %p", strM, strM);
NSLog(@"%@, %p", str, str);
列印結果為:
strM, 0x1268312783
strM, 0x1723009183
以上我們可以發現,使用copy或mutableCopy都有產生新的物件.但是:
NSString *str = @"str";
NSString *str1 = [str copy];
NSLog(@"%@, %p", str, str);
NSLog(@"%@, %p", str1, str1);
列印結果為:
str, 0x123456789
str, 0x123456789
兩個物件地址一樣,所以沒有建立新的物件.
當我們對一個不可變物件使用copy
時,系統是不會建立一個新物件的.因為原來的物件是不可以修改的,拷貝的也是不可以修改的.都不可以修改,所以不會產生影響(符合我們的原則),系統為了節省記憶體,所以不產生新的物件.
所以copy
到底是深拷貝還是淺拷貝,視情況而定.
copy
的記憶體管理:
淺拷貝不會生成新的物件,隨意系統會對以前的物件進行一次retain
.深拷貝會產生新的物件,系統不會對以前的物件進行一次retain