iOS-深複製(mutableCopy)與淺複製(copy),ios-mutablecopy
淺複製:只複製指向對象的指標,而不複製引用對象本身。對於淺複製來說,A和A_copy指向的是同一個記憶體資源,複製的只是一個指標,對象本身資源還是只有一份(對象引用計數+1),那如果我們對A_copy執行了修改操作,那麼發現A引用的對象同樣被修改了。
深複製就好理解了,記憶體中存在了兩份獨立對象本身。
在Objective-C中並不是所有的對象都支援Copy,MutableCopy,遵守NSCopying協議的類才可以發送Copy訊息,遵守NSMutableCopying協議的類才可以發送MutableCopy訊息。
(一).對非集合類對象的copy操作:
在非集合類對象中:
1、對immutable對象進行copy操作,是指標複製,mutableCopy操作時內容複寫;
2、對mutable對象進行copy和mutableCopy都是內容複寫。
用代碼簡單表示如下:
[immutableObject copy] //淺複製
[immutableObject mutableCopy] //深複製
[mutableObject copy] //深複製
[mutableObject mutableCopy] //深複製
代碼:
NSString*string =@"origin";
NSString*stringCopy = [stringcopy];//淺複製複製後的對象不可變
NSMutableString*mStringCopy = [stringmutableCopy];//深複製複製後的對象可變
NSLog(@"%p - %p - %p", string, stringCopy, mStringCopy);
2016-03-03 14:56:44.068 Copy[18197:493711] 0x100001080 - 0x100001080 - 0x1003003e0
查看結果:stringCopy和string的記憶體位址是一樣的,mStringCopy和string的記憶體位址是不一樣的。
NSMutableString*string2 = [NSMutableStringstringWithString:@"origin2"];
NSString*stringCopy2 = [string2copy];//深複製複製後的對象不可變
NSMutableString*mStringCopy2 = [string2mutableCopy];//深複製複製後的對象可變
NSLog(@"%p - %p - %p", string2, stringCopy2, mStringCopy2);
2016-03-03 14:56:44.068 Copy[18197:493711] 0x100103920 - 0x326e696769726f75 - 0x1001039b0
查看結果:mStringCopy2、stringCopy2和string2的記憶體位址都是不一樣的。
(二)、集合類對象的copy與mutableCopy
[immutableObject copy] //淺複製
[immutableObject mutableCopy] //單層深複製
[mutableObject copy] //單層深複製
[mutableObject mutableCopy] //單層深複製
代碼:
NSArray*array =@[@[@"a",@"b"],@[@"c",@"d"]];
NSArray*copyArray = [arraycopy];//淺複製複製後的對象不可變
NSMutableArray*mCopyArray = [arraymutableCopy];//單層深複製複製後的對象可變
NSLog(@"%p - %p - %p", array, copyArray, mCopyArray);
2016-03-03 14:56:44.069 Copy[18197:493711] 0x100600450 - 0x100600450 - 0x1006038e0
查看結果:copyArray和array的記憶體位址是一樣的,mCopyArray和array的記憶體位址是不一樣的。
NSMutableArray*array2 = [NSMutableArrayarrayWithObjects:[NSMutableStringstringWithString:@"a"],@"b",@"c",nil];
NSArray*copyArray2 = [arraycopy];//單層深複製複製後的對象不可變
NSMutableArray*mCopyArray2 = [arraymutableCopy];//單層深複製複製後的對象可變
NSLog(@"%p - %p - %p", array2, copyArray2, mCopyArray2);
2016-03-03 14:56:44.069 Copy[18197:493711] 0x100106fd0 - 0x100600450 - 0x100107020
查看結果:mCopyArray2、copyArray2和array2的記憶體位址都是不一樣的。
(三)、自訂對象的copy
.h檔案
@interfaceComplex :NSObject<NSCopying>//採用NSCoping協議,實現深層拷貝
{
int_real;
int_imaginary;
}
- (void)setReal:(int)real andImg:(int)img;
- (void)Show;
@end
.m檔案
@implementationComplex
-(void)setReal:(int)real andImg:(int)img
{
_real= real;
_imaginary= img;
}
-(void)Show
{
NSLog(@"%d+%di",_real,_imaginary);
}
#pragma mark - NSCopying
-(id)copyWithZone:(NSZone*)zone
{
Complex*p = [ComplexallocWithZone:zone];//申請一塊Complex的記憶體
[psetReal:_realandImg:_imaginary];//拷貝資料
returnp;
}
@end
NSLog(@"------------淺拷貝--------------");
Complex*com1 = [[Complexalloc]init];
[com1setReal:12andImg:3];
//淺拷貝
Complex*com2 = com1;
[com1Show];
[com2Show];
2016-03-03 15:23:43.627 Copy[18424:509266] 12+3i
2016-03-03 15:23:43.627 Copy[18424:509266] 12+3i
[com1setReal:3andImg:5];// com1重新賦值
[com1Show];
[com2Show];
// com1重新賦值,com2隨之變化
2016-03-03 15:23:43.627 Copy[18424:509266] 3+5i
2016-03-03 15:23:43.627 Copy[18424:509266] 3+5i
[com2setReal:10andImg:5];// com2重新賦值
[com1Show];
[com2Show];
// com2重新賦值,com1也隨之變化
2016-03-03 15:23:43.628 Copy[18424:509266] 10+5i
2016-03-03 15:23:43.628 Copy[18424:509266] 10+5i
NSLog(@"------------深拷貝------------");
Complex*comA = [[Complexalloc]init];
[comAsetReal:2andImg:3];
Complex*comB = [comAcopy];//深層拷貝,使用copy方法,但是前提必須實現NSCopying協議中的copyWithZone方法
[comAShow];
[comBShow];
2016-03-03 15:23:43.628 Copy[18424:509266] 2+3i
2016-03-03 15:23:43.628 Copy[18424:509266] 2+3i
[comAsetReal:3andImg:4];// comA重新賦值
[comAShow];
[comBShow];
// comA改變不引起comB變化
2016-03-03 15:23:43.628 Copy[18424:509266] 3+4i
2016-03-03 15:23:43.628 Copy[18424:509266] 2+3i
[comBsetReal:100andImg:2];// comB重新賦值
[comAShow];
[comBShow];
// comB改變不引起comA變化
2016-03-03 15:23:43.628 Copy[18424:509266] 3+4i
2016-03-03 15:23:43.628 Copy[18424:509266] 100+2i