1. 程式人生 > >copy和mutableCopy

copy和mutableCopy

copy和mutableCopy


淺複製:不考慮物件本身,僅僅拷貝指向物件的指標
深複製:是直接拷貝整個物件記憶體到另一塊記憶體中

一般情況下,=基本上都是淺複製:

UIView *view1 = [[UIView alloc] init];
UIView *view2 = [[UIView alloc] init];
view1 = view2;

view1view2的記憶體地址是一樣的.

copy字面意思就是複製.
copymutableCopy都是NSObject的方法,一個NSObject的物件想要使用這兩個方法,類必須實現NSCopying

協議或者NSMutableCopying協議.
如果不遵守協議,直接使用[xxx copy],會直接導致程式崩潰.比如UIView

copy關鍵字特點:
修改源物件的屬性和行為,不會影響副本物件
修改副本物件的屬性和行為,不會影響源物件
一個物件可以通過copymutableCopy方法來建立一個副本物件
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