ios 深淺拷貝學習

2021-05-28 10:33:34 字數 3568 閱讀 3040

這裡主要側重於集合類的深淺拷貝,主要事因為工作的時候遇到這個問題。

首先我們需要有這樣的乙個前提:

[array addobject:obj];

這樣obj的引用計數會增加1,如果使用remove則obj的引用計數會減一。

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

那麼,假設obj只被array擁有:

id temp = [array objectatindex:0];

[array removeobjectatindex:0];

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

(提醒一下,如果用nsstring做測試,要注意@「abc」是常量 :-)  )

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

下面我們就來**一下。

ios提供了copy和mutablecopy方法,顧名思義,copy就是複製了乙個imutable的物件,而mutablecopy就是複製了乙個mutable的物件。以下將舉幾個例子來說明。

1.     系統的非容器類物件 

這裡指的是nsstring,nsnumber等等一類的物件。

nsstring *string = @"origion";

nsstring *stringcopy = [string copy];

nsmutablestring *stringmcopy = [string mutablecopy];

再看下面的例子: 

nsmutablestring *string = [nsmutablestring stringwithstring: @"origion"];

nsstring *stringcopy = [string copy];

nsmutablestring *mstringcopy = [string copy];

nsmutablestring *stringmcopy = [string mutablecopy];

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

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

2.     系統的容器類物件 

指nsarray,nsdictionary等。對於容器類本身,上面討論的結論也是適用的,需要**的是複製後容器內物件的變化。

//copy返回不可變物件,mutablecopy返回可變物件

nsarray *array1 = [nsarray arraywithobjects:@"a",@"b",@"c",nil];

nsarray *arraycopy1 = [array1 copy];

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

nslog(@"array1 retain count: %d",[array1 retaincount]);

nslog(@"array1 retain count: %d",[arraycopy1 retaincount]);

nsmutablearray *marraycopy1 = [array1 mutablecopy];

//marraycopy1是array1的可變副本,指向的物件和array1不同,但是其中的元素和array1中的元素指向的是同乙個物件。marraycopy1還可以修改自己的物件

[marraycopy1 addobject:@"de"];

[marraycopy1 removeobjectatindex:0];

array1和arraycopy1是指標複製,而marraycopy1是物件複製,marraycopy1還可以改變期內的元素:刪除或新增。但是注意的是,容器內的元素內容都是指標複製。

下面用另乙個例子來測試一下。

nsarray *marray1 = [nsarray arraywithobjects:[nsmutablestring stringwithstring:@"a"],@"b",@"c",nil];

nsarray *marraycopy2 = [marray1 copy];

nslog(@"marray1 retain count: %d",[marray1 retaincount]);

nsmutablearray *marraymcopy1 = [marray1 mutablecopy];

nslog(@"marray1 retain count: %d",[marray1 retaincount]);

//marraycopy2,marraymcopy1和marray1指向的都是不一樣的物件,但是其中的元素都是一樣的物件——同乙個指標

//一下做測試

nsmutablestring *teststring = [marray1 objectatindex:0];

//teststring = @"1a1";//這樣會改變teststring的指標,其實是將@「1a1」臨時物件賦給了teststring

nsarray *array = [nsarray arraywithobjects:[nsmutablestring stringwithstring:@"first"],[nsstringstringwithstring:@"b"],@"c",nil];

nsarray *deepcopyarray=[[nsarray alloc] initwitharray: array copyitems: yes];

nsarray* truedeepcopyarray = [nskeyedunarchiver unarchiveobjectwithdata:

[nskeyedarchiver archiveddatawithrootobject: array]];

或者我們自己實現深拷貝的方法(略)。

3.     自定義物件

如果是我們定義的物件,那麼我們自己要實現nscopying,nsmutablecopying這樣就能呼叫copy和mutablecopy了。舉個例子:

@inte***ce myobj : nsobject

@property (nonatomic, retain) nsmutablestring *name;

@property (nonatomic, retain) nsstring *imutablestr;

@property (nonatomic) int age;

@end

@implementation myobj

@synthesize name;

@synthesize age;

@synthesize imutablestr;

- (id)init

return self;}

- (void)dealloc

- (id)copywithzone:(nszone *)zone

- (id)mutablecopywithzone:(nszone *)zone

@end

ios 深淺拷貝學習

這裡主要側重於集合類的深淺拷貝,主要事因為工作的時候遇到這個問題。首先我們需要有這樣的乙個前提 array addobject obj 這樣obj的引用計數會增加1,如果使用remove則obj的引用計數會減一。ios對集合的記憶體處理就是這樣的。那麼,假設obj只被array擁有 id temp ...

iOS基礎 深淺拷貝

其中有兩點需要注意 1 foundation類已經遵守了和 協議,即實現了copy和mutablecopy方法,因此foundation物件可以使用這些方法建立物件的副本或可變副本,例如 nsstring nsdictionary nsarray nsmutablearr 2 在ios中並不是所有的...

深淺拷貝iOS中的

淺 復 制 在複製操作時,對於被複製的物件的每一層複製都是指標複製。深 復 制 在複製操作時,對於被複製的物件至少有一層複製是物件複製。完全複製 在複製操作時,對於被複製的物件的每一層複製都是物件複製。注 1 在複製操作時,對於物件有n層是物件複製,我們可稱作n級深複製,此處n應大於等於1。2 對於...