iOS 深複製和淺複製

2021-07-09 09:01:07 字數 3711 閱讀 4902

一、copy與retain的區別:

1、copy是建立乙個新物件,retain是建立乙個指標,引用物件計數加一。

2、copy屬性表示兩個物件內容相同,新的物件retain為1,與舊有的物件的引用計數無關,舊有物件沒有改變。copy減少物件對上下文的依賴。

3、retain屬性表示兩個物件位址相同(建立乙個指標,指標拷貝),內容相同,這個物件的retain值加1,也就是說retain是指標拷貝,copy是內容拷貝。

二、copy、mutablecopy

1、必須遵守nscopying協議的類可以傳送copy訊息,遵守nsmutablecopying協議的類可以傳送mutablecopying訊息。

2、預設的ios類並沒有遵守這兩個協議,如果想自定義一下copy,那麼就必須遵守nscopying並實現copywithzone:方法,如果想自定義一下mutablecopy,那麼久必須遵守nsmutablecopying並實現mutablecopywithzone:方法。

3、ios提供了copy和mutablecopy方法,copy就是複製乙個不可變的物件,mutablecopy就是複製乙個可變的物件。

4、例1:系統的非容器類物件:nsstring、nsnumber等等的一類物件

nsstring *string = @「origin」;

nsstring *stringcopy = [string copy];

nsmutablestring *stringmutcopy = [string mutablecopy];

nsmutablestring *string  = [nsmutablestring stringwithstring:@「hello」];

nsstring *stringcopy = [string copy];

nsmutablestring *mstringcopy = [string copy];

nsmutablestring *mutstrcopy = [string mutablecopy];

以上四個nsstring物件所分配的記憶體都是不一樣的。但是對於mstringcopy其實是個不可變的物件,所以上述會報錯。

對於系統的非容器類物件,我們可以認為,如果對一不可變物件複製,copy是指標複製(淺拷貝),mutablecopy是物件複製(深拷貝)。如果是對可變物件複製,都是深拷貝,但是copy返回的物件是不可變的。

例2:系統容器類物件(指的是nsarray、nsdictionary等)

copy返回不可變物件,mutablecopy返回的是可變物件。

nsarray *array = [nsarray arraywithobjects:@「a」,@「b」,@「c」,nil];

nsarray *arraycopy = [array copy];

//arraycopy和array同乙個nsarray物件(指向相同的物件),包括array裡面的元素也是指向相同的指標

三、必須使用深拷貝:

[array addobject:obj];//這樣obj的引用計數會加一,如果使用remove則obj的引用計數會減一

ios 對集合的記憶體處理就是這樣的:

假設obj只被array擁有:id temp = [array objectatindex:0];

[array removeobjectatindex:0];

如果你在要使用temp就會出錯,因為這個時候obj已經被釋放了。

由於在程式中經常會遇到集合類的傳值,所以,簡單的retain未必夠用,需要對集合內容的拷貝,也就是深拷貝。

四、可複製物件

nsnumber、nsstring、nsarray、nsdictionary、nsmutabledictionary、nsmutablearray、nsmutablestring。

五、複製物件的基本概念

1、copy方法用於複製物件的不可變副本。通常來說,copy方法總是返回物件的不可修改的副本,即使該物件本身是可修改的。例如:程式呼叫了nsmutablestring的copy方法,將會返回不可修改的字元床物件。

2、mutablecopy方法用於複製物件的可變副本。通常來說,mutablecopy方法總是返回該物件的可修改的副本,即使該物件本身不可修改的,呼叫mutablecopy方法複製出來的副本也是可以修改的。例如:程式呼叫了nsstring的mutablecopy方法,將會返回乙個nsmutablestring物件。

六、複製物件

例1:nsarray *array1 = @[@"one",@"two",@"three",@"four",@"five"];

//使用copy複製乙份array1物件的不可變的副本

nsmutablearray *mutarray = [array1 copy];

//下面這行**會報錯,因為mutaray是不可修改的,編譯時型別是nsmutablearray,執行時實際上卻變成了nsarray型別

[mutarray addobject:@"test"];

例2:nsmutablearray *mutarray = [nsmutablearray arraywithobjects:@"張三",@"李四",@"王五",nil];

//使用muttablecopy複製乙份mutarray物件的可修改的副本

nsarray *array = [mutarray mutablecopy];

//下面這行**可以正確執行,因為arrat實際上是可修改的陣列,編譯時型別為nsarray,執行時實際上卻變成了nsmutablearray型別

因此可以強轉成nsmutablearray型別,同樣可以正確呼叫addobject方法

[(nsmutablearray *)array addobject:@"趙六"];

nslog(@"%li",array.count);

七、淺拷貝和深拷貝的概念

淺拷貝(shallow copy),當物件的屬性是指標變數時,如果程式只是複製該指標的位址,而不是真正複製指標所指向的物件,這種方式被稱為淺拷貝。

深拷貝(deep copy),深拷貝不僅會複製物件本身,而且會「遞迴」複製每個指標型別的屬性,直到兩個物件沒有任何的共用部分為止。

八、**示例:

.h@property(nonatomic,strong)

nsmutablestring

*username;

@property(nonatomic,strong)

nsstring

*userpwd;

@property(nonatomic,assign) intuserage;

-(id)initwithname:(nsmutablestring *)username withpwd:(nsstring *)userpwd;

@end

.m-(id)initwithname:(nsmutablestring *)username withpwd:(nsstring *)userpwd

return self; }

-(nsstring *)description

-(id)copywithzone:(nszone *)zone

注:@property引數使用小結:

1》使用iboutlet屬性的控制項用weak

2》屬性物件用strong(當該物件需要被拷貝的話,就用copy)

3》基本資料型別用assign

4》字串nsstring用copy(nsmutablestring不能使用copy,@property沒有提供mutablecopy,只有copy,只能用strong)

iOS深複製和淺複製

淺複製示例 nsmutablearray marray nsmutablearray arraywithobjects nsmutablestring stringwithstring origiona nsmutablestring stringwithstring origionb nsmuta...

淺複製和深複製

在c 中,下面三種物件需要呼叫拷貝建構函式 有時也稱 複製建構函式 1 乙個物件作為函式引數,以值傳遞的方式傳入函式體 全域性函式,傳入的是物件 void g fun resume c 2 乙個物件作為函式返回值,以值傳遞的方式從函式返回 全域性函式 返回的是物件 resume g fun 3 乙個...

深複製和淺複製

以下 是否完全正確,執行可能得到的結果是 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class a class b b void sayhello b b int main 程式正常執行 程式編譯錯誤 程式崩潰 程式死迴圈 這個程式會直接崩潰 voidsayhello ...