深拷貝就是把內(nèi)容拷貝一份產(chǎn)生一份新的對象,新對象計數(shù)器為1,源對象計數(shù)器不變。
而淺拷貝是指針拷貝,把地址給你,你和我指向同一個對象,源對象計數(shù)器加一,源對象和副本的計數(shù)器相同。
我們知道在OC中的拷貝函數(shù)有copy和mutablecopy,只要你調(diào)用了copy不管是NSString, NSDictionary還是NSArray還是NSMutableString還是NSMutableDictionary,還是NSMutableArray都是copy出來是不可變的副本。
當你調(diào)用mutablecopy產(chǎn)生的都是可變的副本??勺儗ο蠛筒豢勺儗ο筮M行mutablecopy都是產(chǎn)生了一個新的對象,計數(shù)器為1,原來的對象計數(shù)器不變。而如果是copy而且是不可變對象進行copy的話則是淺拷貝沒有產(chǎn)生一個新的對象相當于retain操作了,因為OC設置copy語法本身就是為了改變副本而不去影響源對象,所以為了性能著想既然copy出來的都不可變了,自然也就不會產(chǎn)生一個新的對象了。
可變對象進行copy就是深拷貝因為可變對象變成了不可變對象了,結(jié)構(gòu)上發(fā)生了改變??偨Y(jié)來說就是只有不可變對象調(diào)用copy為淺拷貝其他都是深拷貝。
@property屬性的copy代表的是set方法會release舊對象,copy一個產(chǎn)生新對象其實就是把retain的set方法中最后的retain改成了copy。所以其實就是這個意思.此處title是@property(copy,nonatomic)NSString * title;在manger這個類中
[objc]view plaincopy
NSString*str1=[NSString?stringWithFormat:@"hahha"];
Manger*manger1=[[Manger?alloc]init];
????????manger1.title=str1;??
NSLog(@"%i",manger1.title==str1);//輸出是1,是淺拷貝
[objc]view plaincopy
NSMutableString*str1=[NSMutableString?stringWithFormat:@"hahha"];
Manger*manger1=[[Manger?alloc]init];
???????manger1.title=str1;??
NSLog(@"%i",manger1.title==str1);//輸出為0,是深拷貝
NSString一般都用copy,不過還是得看需求。
如果我們想讓一個類的對象進行拷貝操作就要讓這個類要實現(xiàn)NSCopying或者NSMutableCopying協(xié)議。然后我們還要在類的.m文件中實現(xiàn)-(id)copyWithZone:(NSZone *)zone方法,其中zone指向新的一塊存儲空間,是系統(tǒng)已經(jīng)給我們分配的內(nèi)存。具體實現(xiàn)如下。
[objc]view plaincopy
-(id)copyWithZone:(NSZone*)zone
{??
Manger*copy=[[[self?class]?allocWithZone:zone]init];//這里就是用系統(tǒng)自己給分配的內(nèi)存,此處最好用self?class?來代替類名
copy.title=self.title;
returncopy
}??
總結(jié):可變對象的copy和mutableCopy方法都是深拷貝,而且都是是單層拷貝也就是說我有個數(shù)組a和數(shù)組b,我讓數(shù)組b = [a copy]或者 b = [a mutableCpoy],雖然b的地址和a的地址不同,但是其里面的數(shù)組元素的地址和原數(shù)組里面的對象的地址還是相同的,也就是說數(shù)組內(nèi)容還是指向原數(shù)組里面的元素的。
不可變對象的copy方法是淺拷貝,mutableCopy的方法是深拷貝
copy方法返回的對象都是不可變對象
如果我們想實現(xiàn)數(shù)組中的對象也可以進行深拷貝的話,我們可以這么做,其實就是利用了歸檔的方式
[objc]view plaincopy
-?(void)?deplyFullCopy
{??
NSMutableArray*arrayM1?=?[[NSMutableArray?alloc]?init];
NSMutableString*mstr1?=?[[NSMutableString?alloc]initWithString:@"哈哈"];
NSMutableString*mstr2?=?[[NSMutableString?alloc]initWithString:@"呵呵"];
[arrayM1?addObject:mstr1];
[arrayM1?addObject:mstr2];
NSData*data?=?[NSKeyedArchiver?archivedDataWithRootObject:arrayM1];
NSArray*arrayM2?=?[NSKeyedUnarchiver?unarchiveTopLevelObjectWithData:data?error:nil];
NSLog(@"marry1:%p?---?%@?\r\n",arrayM1,arrayM1);
NSLog(@"marry2:%p?---?%@?\r\n",arrayM2,arrayM2);
NSLog(@"數(shù)組元素地址:value1:%p?---?value2:%p?\r\n",arrayM1[0],arrayM1[1]);
NSLog(@"數(shù)組元素地址:value1:%p?---?value2:%p?\r\n",arrayM2[0],arrayM2[1]);
}??
?