概念
- 淺復制就是兩個變量指向了同一塊內存區(qū)域祟昭;
- 深復制就是兩個變量指向了不同的內存區(qū)域排苍。
淺復制示意圖
深復制示意圖
- 非集合對象:如NSString,NSInteger,NSNumber……
- 集合對象:如NSArray,NSDictionary幽勒,……
結論
1、非集合對象的copy與mutableCopy
- 可變對象的copy和mutableCopy方法都是深復制役纹;
- 不可變對象的copy方法是淺復制蟀瞧,mutableCopy方法是深復制;
- 無論是可變對象還是不可變對象届氢,copy方法返回的對象是不可變對象欠窒。
2、集合對象的copy與mutableCopy
集合對象與非集合對象所遵循的規(guī)則基本上是一樣的退子,唯一差別:
集合對象的深復制并不是嚴格意義上的深復制岖妄,而是單層深復制。
單層深復制:對集合對象來說寂祥,深復制時只是將第一層對象進行了深復制荐虐,內部的對象仍然是淺復制。
3丸凭、集合對象的完全復制
- 方法一:使用 initWith***: copyItems:YES 方法
自定義集合對象使用這個方法福扬,對象必須遵守NSCopying協(xié)議,并重寫- (id)copyWithZone:(NSZone *)zone方法惜犀。(系統(tǒng)類方法已經(jīng)實現(xiàn))铛碑。
代碼及運行結果如下:
#import <Foundation/Foundation.h>
@interface ModelStudent : NSObject<NSCopying>
@property(nonatomic, copy) NSString * name;
@property(nonatomic, assign) NSInteger age;
@property(nonatomic, assign) NSInteger sex;
@end
#import "ModelStudent.h"
@implementation ModelStudent
- (id)copyWithZone:(NSZone *)zone{
ModelStudent * s = [[ModelStudent alloc]init];
s.name = self.name;
s.age = self.age;
s.sex = self.sex;
return s;
}
@end
ModelStudent * model1 = [ModelStudent new];
model1.name = @"mao";
model1.age = 14;
ModelStudent * model2 = [ModelStudent new];
model2.name = @"mao";
model2.age = 14;
self.arr = @[model1, model2];
//完全深復制
NSArray * array4 = [[NSArray alloc]initWithArray:self.arr copyItems:YES];
NSLog(@"%@,%@", self.arr, array4);
運行結果
- 方法二:先將集合進行歸檔,然后再解檔虽界。
通常我們對模型數(shù)組完全復制汽烦,先將模型數(shù)組轉換為data數(shù)組,再將data數(shù)組轉換為模型數(shù)組莉御,即可刹缝。代碼如下:
#import <Foundation/Foundation.h>
@interface ModelStudent : NSObject<NSCoding>
@property(nonatomic, copy) NSString * name;
@property(nonatomic, assign) NSInteger age;
@property(nonatomic, assign) NSInteger sex;
@end
#import "ModelStudent.h"
@implementation ModelStudent
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:@(self.age) forKey:@"age"];
[aCoder encodeObject:@(self.sex) forKey:@"sex"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [[aDecoder decodeObjectForKey:@"age"] integerValue];
self.sex = [[aDecoder decodeObjectForKey:@"sex"] integerValue];
}
return self;
}
@end
ModelStudent * model1 = [ModelStudent new];
model1.name = @"mao";
model1.age = 14;
ModelStudent * model2 = [ModelStudent new];
model2.name = @"mao";
model2.age = 14;
self.arr = @[model1, model2];
NSMutableArray * arr2 = [self.arr mutableCopy];
//完全深復制
//先歸檔
NSMutableArray * mDatas = [NSMutableArray arrayWithCapacity:0];
for (ModelStudent * model in self.arr) {
NSData * data = [NSKeyedArchiver archivedDataWithRootObject:model];
[mDatas addObject:data];
}
//再解檔
NSMutableArray * mModels = [NSMutableArray arrayWithCapacity:0];
for (NSData * data in mDatas) {
ModelStudent * model = [NSKeyedUnarchiver unarchiveObjectWithData:data];
[mModels addObject:model];
}
NSLog(@"非完全深復制:%@---%@", self.arr, arr2);
NSLog(@"完全深復制:%@---%@", self.arr, mModels);
打印結果
參考
iOS中的深復制與淺復制
NSObject 有個copyWithZone是什么作用?
iOS學習筆記系列 - OC如何正確重寫copyWithZone