iOS 理解copy與mutableCopy

SunnyD發表於2017-12-14

不管是集合類物件,還是非集合類物件,接收到copy和mutableCopy訊息時,都遵循以下準則:

  • copy返回imutable物件;所以,如果對copy返回值使用mutable物件介面就會crash;
  • mutableCopy返回mutable物件;

###1.非集合類物件的copy與mutableCopy### 系統非集合類物件指的是 NSString, NSNumber ... 之類的物件。下面先看個非集合類immutable物件拷貝的例子

NSString *string = @"origin";
NSString *stringCopy = [string copy];
NSMutableString *stringMCopy = [string mutableCopy];
複製程式碼

通過檢視記憶體,可以看到 stringCopy 和 string 的地址是一樣,進行了指標拷貝;而 stringMCopy 的地址和 string 不一樣,進行了內容拷貝;

再看mutable物件拷貝例子

NSMutableString *string = [NSMutableString stringWithString: @"origin"];
//copy
NSString *stringCopy = [string copy];
NSMutableString *mStringCopy = [string copy];
NSMutableString *stringMCopy = [string mutableCopy];
//change value
[mStringCopy appendString:@"mm"]; //crash
[string appendString:@" origion!"];
[stringMCopy appendString:@"!!"];
複製程式碼

執行以上程式碼,會在第7行crash,原因就是 copy 返回的物件是 immutable 物件。註釋第7行後再執行,檢視記憶體,發現 string、stringCopy、mStringCopy、stringMCopy 四個物件的記憶體地址都不一樣,說明此時都是做內容拷貝。

綜上兩個例子,我們可以得出結論:

在非集合類物件中:對immutable物件進行copy操作,是指標複製,mutableCopy操作時內容複製;對mutable物件進行copy和mutableCopy都是內容複製。用程式碼簡單表示如下:

  • [immutableObject copy] // 淺複製
  • [immutableObject mutableCopy] //深複製
  • [mutableObject copy] //深複製
  • [mutableObject mutableCopy] //深複製

###2、集合類物件的copy與mutableCopy### 集合類物件是指NSArray、NSDictionary、NSSet ... 之類的物件。下面先看集合類immutable物件使用copy和mutableCopy的一個例子:

NSArray *array = @[@[@"a", @"b"], @[@"c", @"d"];
NSArray *copyArray = [array copy];
NSMutableArray *mCopyArray = [array mutableCopy];
複製程式碼

檢視內容,可以看到copyArray和array的地址是一樣的,而mCopyArray和array的地址是不同的。說明copy操作進行了指標拷貝,mutableCopy進行了內容拷貝。但需要強調的是:此處的內容拷貝,僅僅是拷貝array這個物件,array集合內部的元素仍然是指標拷貝。這和上面的非集合immutable物件的拷貝還是挺相似的,那麼mutable物件的拷貝會不會類似呢?我們繼續往下,看mutable物件拷貝的例子:

NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray *copyArray = [array copy];
NSMutableArray *mCopyArray = [array mutableCopy];
複製程式碼

檢視記憶體,如我們所料,copyArray、mCopyArray和array的記憶體地址都不一樣,說明copyArray、mCopyArray都對array進行了內容拷貝。同樣,我們可以得出結論:

在集合類物件中,對immutable物件進行copy,是指標複製,mutableCopy是內容複製;對mutable物件進行copy和mutableCopy都是內容複製。但是:集合物件的內容複製僅限於物件本身,物件元素仍然是指標複製。用程式碼簡單表示如下:

  • [immutableObject copy] // 淺複製
  • [immutableObject mutableCopy] //單層深複製
  • [mutableObject copy] //單層深複製
  • [mutableObject mutableCopy] //單層深複製

參考連結:iOS 集合的深複製與淺複製

相關文章