copy和mutableCopy實踐

首先說下兩個基本定義:
淺復(fù)制:只copy指針而不是copy實際的資源,兩個實例指向內(nèi)存中同一資源。
深復(fù)制:不僅復(fù)制指針,還復(fù)制指針?biāo)赶虻馁Y源,會開辟一塊內(nèi)存存放拷貝的資源。

不可變對象的copy和mutableCopy操作:

不可變數(shù)組
NSArray *arr = [NSArray array];
NSMutableArray  *arr1 = arr.copy;
NSMutableArray *arr2 = arr.mutableCopy;
NSLog(@"%p--%p--%p",arr,arr1,arr2);//0x60800001a1b0--0x60800001a1b0--0x608000047290 
[arr2 insertObject:@"1" atIndex:0];//插入元素成功
[arr1 insertObject:@"1" atIndex:0];//'-[__NSArray0 insertObject:atIndex:]: unrecognized selector sent to instance

 不可變字典
 NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:@"value1",@"key1",@"value2",@"key2", nil];
 NSMutableDictionary *dicM = dict1.copy;
 NSMutableDictionary *dicM1 = dict1.mutableCopy;
 NSLog(@"%p--%p--%p",dict1,dicM,dicM1);//0x6000002641c0--0x6000002641c0--0x600000045280
 [dicM1 removeObjectForKey:@"key1"];
    Printing description of dicM1:
   {
      key2 = value2;
   }

 [dicM removeObjectForKey:@"key1"];//-[__NSDictionaryI removeObjectForKey:]: unrecognized selector sent to instance

 不可變字符串
 NSString *str = @"123";
 NSMutableString *strM1 = str.copy;
 NSMutableString *strM2 = str.mutableCopy;
 NSLog(@"%p--%p--%p",str,strM1,strM2);// 0x1047ee068--0x1047ee068--0x608000079800
 [strM2 appendString:@"4"];//Printing description of strM2:
1234
 [strM1 appendString:@"5"]; //Attempt to mutate immutable object with appendString:   

結(jié)論:對不可變對象進(jìn)行copy操作,不會開辟新的內(nèi)存,copy的只是內(nèi)存地址;對不可變對象進(jìn)行mutableCopy操作,會開辟新的內(nèi)存,拷貝出的對象是可變的;

可變對象的copy和mutableCopy操作:

可變數(shù)組
NSMutableArray *arrM = [NSMutableArray arrayWithCapacity:0];
NSMutableArray *arrM1 = arrM.copy;
NSMutableArray *arrM2 = arrM.mutableCopy;
NSLog(@"%p--%p--%p",arrM,arrM1,arrM2);//arrM:0x608000047e60--arrM1:0x60800000f160--arrM2:0x608000047ce0
[arrM insertObject:@"2" atIndex:0];
[arrM2 insertObject:@"3" atIndex:0];
[arrM1 addObject:@"1"];//-[__NSArray0 addObject:]: unrecognized selector sent to instance


可變字典
NSMutableDictionary *dict1 = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1",@"key1",@"value2",@"key2", nil];
NSMutableDictionary *dicM = dict1.copy;
NSMutableDictionary *dicM1 = dict1.mutableCopy;
NSLog(@"%p--%p--%p",dict1,dicM,dicM1);//0x60000005d7f0--0x600000074780--0x60000005b810
[dicM1 removeObjectForKey:@"key1"];
 Printing description of dicM1:
   {
      key2 = value2;
   }

[dicM removeObjectForKey:@"key1"];//-[__NSDictionaryI removeObjectForKey:]: unrecognized selector sent to instance

可變字符串
NSMutableString *str = [NSMutableString stringWithCapacity:0]; 
NSMutableString *strM1 = str.copy;
NSMutableString *strM2 = str.mutableCopy;
NSLog(@"%p--%p--%p",str,strM1,strM2);//0x6080000716c0--0x103d94570--0x608000071680
[strM2 appendString:@"4"];//Printing description of strM2:
4
[strM1 appendString:@"5"];//Attempt to mutate immutable object with appendString:

結(jié)論:對可變對象進(jìn)行copy操作,會開辟新的內(nèi)存,拷貝出的對象是不可變的;對可變對象進(jìn)行mutableCopy操作,會開辟新的內(nèi)存,拷貝出的對象是可變的;

關(guān)于有可變類型的不可變類(如NSDictionary,NSArray,NSString),聲明屬性時內(nèi)存管理關(guān)鍵字為什么要用copy?

用strong聲明結(jié)果如下:

strong.png
arrStrong.png
strStrong.png

用copy聲明結(jié)果如下:

copy.png
arrCopy.png
strCopy.png

屬性為可變類型,用strong定義,當(dāng)屬性賦值時接收的對象為可變對象,而該可變對象的值改變時,屬性的值也跟著改變了。而用copy修飾,賦值時會拷貝出一個新的不可變對象,不受該可變對象影響;

從上面的結(jié)果能看出copy不等于淺復(fù)制,而mutableCopy一定是深復(fù)制。這是因為拷貝后只要副本和原對象之間相互不影響即可,對于OC中這些不可變的對象,因為他們的值是不能修改的,所以副本和原對象之間滿足相互不影響,沒必要新開辟內(nèi)存空間拷貝一份資源。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容