深拷貝和淺拷貝

以下文章是我參照了一些大神的文章加上自己實驗得出的結論,有疑問的可以評論提出來,大家互相討論下。

首先我們來了解下retain和copy的區別,由于現在使用的是ARC環境,所以基本上用不上retain了,所以我對深淺拷貝這方面還是挺迷糊的。

retain:引用計數+1,指針復制 。

這個例子就很好的說明了retain是指針復制,兩個數組指向同一個內存,如果這里打印marr2的retainCount的話就會是2。而且當marr3添加元素時,marr2一樣添加了元素,因為他們使用的是同一個內存

copy:對象復制。

例子寫的low了點,自己寫隨便玩

這個結果就可以很明顯看出retain和copy的的區別,copy出來的可變數組添加元素的時候,原來的數組是不會有變化的,這就表明他們是存在不同內存的。

注意:copy對于數值型的對象是深拷貝,但是對于容器型對象,例如字典、數組其實不算是真正意義上的深拷貝,因為copy過來的新的容器對象中的元素指向的內存還是跟原來一樣。看代碼圖:

從結果就可以看出,不管是retain還是copy的,容器對象中的元素指針所指向的內存地址都是沒有變化的。

真正的深拷貝:

trueDeepCopyArray是完全意義上的深拷貝,而deepCopyArray則不是,對于deepCopyArray內的不可變元素其還是指針復制。或者我們自己實現深拷貝的方法。因為如果容器的某一元素是不可變的,那你復制完后該對象仍舊是不能改變的,因此只需要指針復制即可。除非你對容器內的元素重新賦值,否則指針復制即已足夠。舉個例子,[[array objectAtIndex:0]appendstring:@”sd”]后其他的容器內對象并不會受影響。[[array objectAtIndex:1]和[[deepCopyArray objectAtIndex:0]盡管是指向同一塊內存,但是我們沒有辦法對其進行修改——因為它是不可改變的。所以指針復制已經足夠。所以這并不是完全意義上的深拷貝


接下來說說自定義對象的拷貝:

如果是我們定義的對象,那么我們自己要實現NSCopying,NSMutableCopying這樣就能調用copy和mutablecopy了。

這樣拷貝出來的Prototype對象中的屬性str內存地址是一樣的,不算真正意義上的深拷貝

這樣拷貝出來的Prototype對象中的屬性str內存地址就不一樣了,才是真正意義上的深拷貝!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容