iOS 單層深復(fù)制與完全深復(fù)制

概念

  • 淺復(fù)制就是兩個變量指向了同一塊內(nèi)存區(qū)域;
  • 深復(fù)制就是兩個變量指向了不同的內(nèi)存區(qū)域。
淺復(fù)制示意圖
深復(fù)制示意圖
  • 非集合對象:如NSString,NSInteger,NSNumber……
  • 集合對象:如NSArray,NSDictionary,……

結(jié)論

1、非集合對象的copy與mutableCopy

  • 可變對象的copy和mutableCopy方法都是深復(fù)制;
  • 不可變對象的copy方法是淺復(fù)制,mutableCopy方法是深復(fù)制;
  • 無論是可變對象還是不可變對象,copy方法返回的對象是不可變對象。

2、集合對象的copy與mutableCopy

集合對象與非集合對象所遵循的規(guī)則基本上是一樣的,唯一差別:
集合對象的深復(fù)制并不是嚴(yán)格意義上的深復(fù)制,而是單層深復(fù)制。

單層深復(fù)制:對集合對象來說,深復(fù)制時只是將第一層對象進(jìn)行了深復(fù)制,內(nèi)部的對象仍然是淺復(fù)制。

3、集合對象的完全復(fù)制

  • 方法一:使用 initWith***: copyItems:YES 方法
    自定義集合對象使用這個方法,對象必須遵守NSCopying協(xié)議,并重寫- (id)copyWithZone:(NSZone *)zone方法。(系統(tǒng)類方法已經(jīng)實現(xiàn))。

代碼及運行結(jié)果如下:

#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];
    
    //完全深復(fù)制
    NSArray * array4 = [[NSArray alloc]initWithArray:self.arr copyItems:YES];
    NSLog(@"%@,%@", self.arr, array4);
運行結(jié)果
  • 方法二:先將集合進(jìn)行歸檔,然后再解檔。
    通常我們對模型數(shù)組完全復(fù)制,先將模型數(shù)組轉(zhuǎn)換為data數(shù)組,再將data數(shù)組轉(zhuǎn)換為模型數(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];
    //完全深復(fù)制
    //先歸檔
    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(@"非完全深復(fù)制:%@---%@", self.arr, arr2);
    NSLog(@"完全深復(fù)制:%@---%@", self.arr, mModels);
打印結(jié)果

參考

iOS中的深復(fù)制與淺復(fù)制
NSObject 有個copyWithZone是什么作用?
iOS學(xué)習(xí)筆記系列 - OC如何正確重寫copyWithZone

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容