對Copy 和 MutableCopy全面理解

對Copy 和 MutableCopy全面理解

所有的copy出來的對象都是不可變的,所有mutableCopy出來的對象都是可變的。immutable對象copy不會開辟新空間,mutableCopy會開辟新空間;mutable對象copy和mutableCopy都會開辟新空間。拷貝分為深拷貝(內容拷貝)、淺拷貝(指針拷貝)。


  • 總是覺得對于copy和mutableCopy已經很理解了,但是前兩天面試官一問,感覺又有點小迷惑了,總覺還是沒有真正好好的總結一下的原因,故此,總結一下,并且用實際的代碼證明

  • 非集合類 copy 和mutableCopy

    • NSString 和 NSMutableString 的 copy 和 mutableCopy

      • 首先總結一下NSString 的 copy 和 mutableCopy

        • NSString:不可變字符串,即一旦指針指向的這塊內存是不可變的,那么內存空間的內容就是不可修改的

        • copy:NSString copy 淺拷貝,也叫指針拷貝,也就是內存地址沒有發生變化,只是用另外一個指針也指向這個內存空間, copy 出來的對象的當然還是不可變的字符串了(內存地址都沒變么)

        • 翠花上代碼:

           NSString *str2 = @"helloWorld";
          NSString *str3 = [str2 copy];
          NSLog(@"Str3: %@ --%p --%p", str3, str3, &str3);
          NSLog(@"Str2: %@ --%p --%p", str2, str2, &str2);
          
          

    打印結果

    Str3: helloWorld --0x1003304e8 --0x7ffeef8cfb70
    Str2: helloWorld --0x1003304e8 --0x7ffeef8cfb78
    
    
        * 我們可以佐證我的結論:內存地址沒有變化,不同的指針指向這個內存空間而已
        * **mutableCopy**:NSString 的 mutableCopy 屬于深拷貝(什么叫深拷貝,深拷貝就是復制與copy對象內容相同一個副本,放在新的內存空間),copy出來的對象是一個不可變的字符串
        * 翠花上代碼:
    
    
    NSString *str2 = @"helloWorld";
    NSString *str3 = [str2 mutableCopy];
    NSLog(@"Str3: %@ --%p --%p", str3, str3, &str3);
    NSLog(@"Str2: %@ --%p --%p", str2, str2, &str2);
    
    

    打印結果:

    helloWorld --0x60400025dc70 --0x7ffee4717b70
    helloWorld --0x10b4e84e8 --0x7ffee4717b78
    
    

    也可以佐證的結論,內存地址果然變了,當然如果需要看類型的可以打斷點去看真正的類型,str3是不可變的字符串類型

    • NSMutableString copy 和 mutableCopy
    • NSMutableString:可變字符串,即內存空間的內容可以被修改
    • 總結結論:NSMutableCopy 的 copy 和 mutableCopy都是深拷貝,都會重新開辟內存空間,而mutableCopy拷貝出來的是一個可變對象,copy出來的是一個不可變對象
    • 翠花上代碼:
      NSMutableString *strM1 = [NSMutableString stringWithString:@"hello"]; NSMutableString *strM2 = [strM1 copy]; // NSMutableString *strM2 = [strM1 mutableCopy]; NSLog(@"strM1: %@ --Mp_%p --Pp_%p --C_%@", strM1, strM1, &strM1, NSStringFromClass([strM1 class])); NSLog(@"strM2: %@ --Mp_%p --Pp_%p --C_%@", strM2, strM2, &strM2, NSStringFromClass([strM2 class]));
      copy 打印出
      strM1: hello --Mp_0x600000253290 --Pp_0x7ffeef64eb78 --C___NSCFString // __NSCFString 就是MutableString strM2: hello --Mp_0xa00006f6c6c65685 --Pp_0x7ffeef64eb70 --C_NSTaggedPointerString // NSTaggedPointerString 是不可變字符串
      我們可以看出內存地址發生了變化,指針地址也發生了變化,當然類型也是不一樣的
      mutableCopy打印
    strM1: hello --Mp_0x60400024b6a0 --Pp_0x7ffeea677b78 --C___NSCFString
    strM2: hello --Mp_0x60400024b6d0 --Pp_0x7ffeea677b70 --C___NSCFString
    
    

    我們可以看出內存地址發生了變化,指針地址也發生了變化,但是都是可變的String

    • 最后的總結:NSString 不可變對象copy淺拷貝(指針拷貝),copy出來的對象不可變,mutableCopy 深拷貝,拷貝出來的對象不可變;NSMutableString copy 深拷貝,拷貝出來的對象不可變,mutableCopy 深拷貝,拷貝出來的對象也是可變的
  • 集合類對象的copy 和 mutableCopy

    • NSArray copy 和 muatbleCopy

      • 總結:不可變集合類copy是淺拷貝指針拷貝,拷貝出來的對象是不可變的,這一點和非集合類是一樣的;mutableCopy 是不完全拷貝,數組的是深拷貝,但是里邊的地址是指針拷貝

      • 翠花上代碼:

        • copy
          NSArray *array = @[@"123", @"456"]; NSArray *array2 = [array copy]; NSLog(@"array: %@ --Mp_%p --Pp_%p --C_%@ --firstM_%p", array, array, &array, NSStringFromClass([array class]), array.firstObject); NSLog(@"array2: %@ --Mp_%p --Pp_%p --C_%@ --firstM_%p", array2, array2, &array2, NSStringFromClass([array2 class]), array2.firstObject);
          打印結果:
          array: ( 123, 456 ) --Mp_0x604000222180 --Pp_0x7ffee1aceb60 --C___NSArrayI --firstM_0x10e1314f0 array2: ( 123, 456 ) --Mp_0x604000222180 --Pp_0x7ffee1aceb58 --C___NSArrayI --firstM_0x10e1314f0
          我們可以看到,不可變集合類對象copy之后,內存地址并沒有發生變化,里邊元素的地址也沒有發生變化
        • mutableCopy
          NSArray *array = @[@"123", @"456"]; NSArray *array2 = [array mutableCopy]; NSLog(@"array: %@ --Mp_%p --Pp_%p --C_%@ --firstM_%p", array, array, &array, NSStringFromClass([array class]), array.firstObject); NSLog(@"array2: %@ --Mp_%p --Pp_%p --C_%@ --firstM_%p", array2, array2, &array2, NSStringFromClass([array2 class]), array2.firstObject);
          打印結果:
          array: ( 123, 456 ) --Mp_0x604000032580 --Pp_0x7ffee9b60b70 --C___NSArrayI --firstM_0x10609f4f0 array2: ( 123, 456 ) --Mp_0x60400024fba0 --Pp_0x7ffee9b60b68 --C___NSArrayM --firstM_0x10609f4f0
          我們可以發現數組的內存地址放生了變化,但是數組的元素地址并沒有發生變化
    • NSMuatbleArray copy 和 mutableCopy

      • 總結:可變數組的copy 也屬于不完全深拷貝,數組深拷貝,數組內容淺拷貝,副本不可變對象;可變數組mutableCopy,不完全深拷貝,數組深拷貝,內容淺拷貝,副本可變對象
      • 翠花上代碼:
      • copy
        NSMutableArray *array = [NSMutableArray arrayWithObjects:@"123", @"456", nil]; NSArray *array2 = [array copy]; NSLog(@"array: %@ --Mp_%p --Pp_%p --C_%@ --firstM_%p", array, array, &array, NSStringFromClass([array class]), array.firstObject); NSLog(@"array2: %@ --Mp_%p --Pp_%p --C_%@ --firstM_%p", array2, array2, &array2, NSStringFromClass([array2 class]), array2.firstObject);
        打印:
        array: ( 123, 456 ) --Mp_0x600000247380 --Pp_0x7ffee2afab78 --C___NSArrayM --firstM_0x10d1054e0 array2: ( 123, 456 ) --Mp_0x600000036e40 --Pp_0x7ffee2afab70 --C___NSArrayI --firstM_0x10d1054e0
        我們發現內存地址發生了變化,并且copy之后的類型是不可變的,第一個元素的地址還是一樣的
      • mutableCopy
        NSMutableArray *array = [NSMutableArray arrayWithObjects:@"123", @"456", nil]; NSArray *array2 = [array mutableCopy]; NSLog(@"array: %@ --Mp_%p --Pp_%p --C_%@ --firstM_%p", array, array, &array, NSStringFromClass([array class]), array.firstObject); NSLog(@"array2: %@ --Mp_%p --Pp_%p --C_%@ --firstM_%p", array2, array2, &array2, NSStringFromClass([array2 class]), array2.firstObject);
        打印:
        array: ( 123, 456 ) --Mp_0x6040002522d0 --Pp_0x7ffeebfe0b78 --C___NSArrayM --firstM_0x103c1f4e0 array2: ( 123, 456 ) --Mp_0x604000252300 --Pp_0x7ffeebfe0b70 --C___NSArrayM --firstM_0x103c1f4e0
        我們發現數組內存地址發生了變化,類型沒有發生變化,都是可變類型,第一個元素的內存地址沒有發生變化。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容