1. 程式人生 > >iOS strong、copy關鍵字之深淺拷貝

iOS strong、copy關鍵字之深淺拷貝

前言

可以選擇簡書檢視本文章

大家都知道在定義屬性時會使用關鍵字nonatomic,strong,copy,weak,assign,但是關於copy關鍵字到底掌握多少呢,下面這個寫法會有什麼問題嗎?

@property (nonatomic, copy) NSMutableString *mutableStr;

strong 和 copy 的區別

  • 第一種情況(傳遞不可變資料)
    定義兩個NSString字串,一個用關鍵strong ,一個用copy,定義不可變字串str,將他賦值給其他兩個。

螢幕快照 2017-08-31 下午2.14.48.png
列印結果:內容相同,記憶體地址是同一個地址,說明這是指標指向了同一地址而已(這是的copy即是淺拷貝,只是拷貝了指標)

注意:上面這種賦值方法有問題,你發現了嗎?(第二種方法中更改了)

  • 第二種情況(傳遞可變資料)
    這裡將區域性的字串改成了可變的NSMutableString,賦值用了self.語法,只有這樣才會走自動生成的setter方法,strong,copy關鍵字才會生效

螢幕快照 2017-08-31 下午2.22.32.png
列印結果:
1.我們發現這個時候使用copy關鍵字的字串的記憶體地址更改了(這個copy即是深拷貝,拷貝了內容)
2.在str更改後,strstrong字串內容也改變了,strCopy內容沒有改變,這裡就是為什麼我們要使用copy關鍵字的原因,因為如果使用strong當你傳遞資料過來時,只是傳遞了指標,要是原來的資料不小心進行了更改,會造成傳遞後的資料也更改了,而使用copy關鍵字的資料則不會出現這個問題。
螢幕快照 2017-08-31 下午2.22.39.png

  • 第三種情況(使用copy關鍵字的字串為NSMutableString)
    使用copy關鍵字的為可變字串,但是結果是什麼呢?

螢幕快照 2017-08-31 下午2.44.54.png

列印結果:
當執行到上圖中的那一句時崩潰了,列印資訊如下圖
因為copy出來的仍然是不可變字元!如果使用NSMutableString的方法,就會崩潰。文章開始的時候那個問題的答案就在這裡了。

  • 第四種情況(疑問)
    如果將第一種情況的不可變字串str重新賦值,那麼strStrong和strCopy會更改嗎?
    當然不會,因為重新賦值會有新的記憶體地址,和原來的資料就沒什麼關係了。原來的記憶體沒有指標指向時就會釋放了。
    螢幕快照 2017-08-31 下午2.56.25.png

總結

1、關於strong和copy的選擇,一般strong和copy是一樣的,但是當你覺得這個值在傳遞後有可能會更改,那麼最好使用copy。
2、對於copy的使用情況,NSArray,NSDictionary同樣適用
3、對於使用copy關鍵字的資料型別,不要定義為可變資料型別(會被罵的)

能力有限,有什麼不對的地方望批評指正

參考