1. 程式人生 > >ios-深拷貝和淺拷貝

ios-深拷貝和淺拷貝

一、深拷貝和淺拷貝

  • 深拷貝:物件拷貝 - 直接拷貝內容。
  • 淺拷貝:指標拷貝 - 將指標中的地址值拷貝一份。
(淺拷貝只是拷貝指向物件的指標,不拷貝引用物件本身,兩者共用一個物件,當記憶體銷燬的時候,指向物件的幾個指標需要重新定義才可以使用,要不然會成為野指標;深拷貝拷貝引用物件本身。)
二、對於 Copy 與 mutableCopy 的實踐
  • 思路:我用四個方案來驗證 Copy 與 mutableCopy 的區別。
  • 方案:

    • 方案一:copy不可變的字串

      NSString*str = @"aaa";
      NSString*copyStr = [str copy];
      NSLog(@"str = %p copyStr= %p"
      ,str,copyStr); NSLog(@"指標地址:str = %p copyStr= %p",&str,&copyStr);

      輸出結果:str = 0x104d94068 copyStr= 0x104d94068
      指標地址:str = 0x7fff529e9aa8 copyStr= 0x7fff529e9aa0
      小結:對不可變的字串的copy,我們物件的記憶體地址沒有改變,只是指標的地址改變了,所以在這裡我們預設進行了一次淺拷貝,只拷貝了指標。

    • 方案二:copy可變的字串

      NSMutableString*str1 = [NSMutableString stringWithFormat:@"bbb"
      ]; NSString*copyStr1 = [str1 copy]; NSLog(@"str1 = %p copyStr1 = %p",str1,copyStr1); NSLog(@"str1 = %p copyStr1= %p",&str1,&copyStr1);

      輸出結果:str1 = 0x7fa522712cd0 copyStr1 = 0x7fa522717ba0
      指標地址:str1 = 0x7fff529e9a98 copyStr1= 0x7fff529e9a90
      小結:對可變字串的copy,我們預設進行了一次深拷貝,直接拷貝了物件。

    • 方案三:mutableCopy不可變的字串
      NSString
      *str2 = @"ccc"; NSMutableString *copyStr2 = [str2 mutableCopy]; NSLog(@"str2 = %p copyStr2 = %p",str2,copyStr2);
      輸出結果:str2 = 0x10d216108 copyStr2 = 0x7fa522726290
      小結:對於不可變字串的mutableCopy我們預設進行了深拷貝。
    • 方案四:mutableCopy可變的字串
      NSMutableString*str3 = [NSMutableString stringWithFormat:@"ddd"];
      NSMutableString*copyStr3 = [str3 mutableCopy];
      NSLog(@"str3 = %p copyStr3 = %p",str3,copyStr3);
      輸出結果:str3 = 0x7fa5227153c0 copyStr3 = 0x7fa5227263f0
      小結:對於可變字串的mutableCopy我們預設進行了深拷貝。

三、結論

  • copy:因為copy預設返回的是不可變的,所以當我們對一個不可變的字串進行copy的時候,我們只是拷貝了它的指標(淺拷貝)。當我們對一個可變的字串進行拷貝的時候,因為型別轉變了,我們需對其進行深拷貝
  • mutableCopy:預設返回的是一個可變的物件,適用於可變的物件,例如NSMutableString,NSMutableArray,NSMutableDictionary、etc。無論對於可變的字串還是不可變的字串進行mutableCopy,系統都預設進行深拷貝,那麼為什麼對於相同型別的進行mutableCopy返回的仍然是新的物件呢,因為在這裡系統要保證,舊的物件和新的物件都是可變的,且他們之間不會相互影響。


原文連結:http://www.jianshu.com/p/63239d4d65e0 相關內容:https://segmentfault.com/a/1190000000604331