深拷贝和浅拷贝

221 阅读4分钟

  • 指针地址,数据地址, 数据

非容器不可变对象

  • 浅拷贝不开辟新内存,数据不可变
  • 深拷贝开辟新内存,数据可变
    NSString *str1 = @"非容器不可变对象";
    NSMutableString *str2 = [str1 copy];
    NSMutableString *str3 = [str1 mutableCopy];
    // [str2 appendString:@" 更改"]; //崩溃
    [str3 appendString:@" 更改"];
    
    NSLog(@"str1: %@, str1_p : %p, class: %@",str1, str1, [str1 class]);
    NSLog(@"str2: %@, str2_p : %p, class: %@",str2, str2, [str2 class]);
    NSLog(@"str3: %@, str3_p : %p, class: %@",str3, str3, [str3 class]);
    str1: 非容器不可变对象, str1_p : 0x10c687020, class: __NSCFConstantString
    str2: 非容器不可变对象, str2_p : 0x10c687020, class: __NSCFConstantString
    str3: 非容器不可变对象 更改, str3_p : 0x6000005dcc60, class: __NSCFString

非容器可变对象

  • 浅拷贝开辟新内存,数据不可变
  • 深拷贝开辟新内存,数据可变
    NSMutableString *str1 = [NSMutableString stringWithFormat:@"非容器可变对象"];
    NSMutableString *str2 = [str1 copy];
    NSMutableString *str3 = [str1 mutableCopy];
    // [str2 appendString:@"更改"]; 崩溃
    [str3 appendString:@"更改"];
    
    NSLog(@"str1: %@, str1_p : %p, class: %@",str1, str1, [str1 class]);
    NSLog(@"str2: %@, str2_p : %p, class: %@",str2, str2, [str2 class]);
    NSLog(@"str3: %@, str3_p : %p, class: %@",str3, str3, [str3 class]);
    str1: 非容器可变对象, str1_p : 0x6000007b9fe0, class: __NSCFString
    str2: 非容器可变对象, str2_p : 0x6000007b9d40, class: __NSCFString
    str3: 非容器可变对象更改, str3_p : 0x6000007b9d70, class: __NSCFString

#容器非可变对象

  • 浅拷贝不开辟新内存,数据不可变,容器类数据只拷贝指针
  • 深拷贝开辟新内存,数据可变,容器类数据只拷贝指针
    NSArray *array = [NSArray arrayWithObjects:str1, @"6789", nil];
    NSMutableArray *copyArray = [array copy];
    NSMutableArray *mutableCopyArray = [array mutableCopy];
    [str1 appendString:@"-abc"];
    //[copyArray addObject:@"efg"]; 崩溃
    [mutableCopyArray addObject:@"efg"];
    
    NSLog(@"array_p: %p, class: %@", array, [array class]);
    NSLog(@"copyArray_p: %p, class: %@", copyArray, [copyArray class]);
    NSLog(@"mutableCopyArray_p: %p, class: %@", mutableCopyArray, [mutableCopyArray class]);
    
    NSLog(@"======原对象=====");
    NSLog(@"arr[0]:%@  object_p: %p, class: %@", array[0], array[0], [array[0] class]);
    NSLog(@"arr[1]:%@ object_p: %p, class: %@", array[1], array[1], [array[1] class]);
    
    NSLog(@"======copy对象=====");
    NSLog(@"arr[0]:%@ object_p: %p, class: %@", copyArray[0], copyArray[0], [copyArray[0] class]);
    NSLog(@"arr[1]:%@ object_p: %p, class: %@", copyArray[1], copyArray[1], [copyArray[1] class]);
    
    NSLog(@"======mutableCopy对象=====");
    NSLog(@"arr[0]:%@ object_p: %p, class: %@", mutableCopyArray[0], mutableCopyArray[0], [mutableCopyArray[0] class]);
    NSLog(@"arr[1]:%@ object_p: %p, class: %@", mutableCopyArray[1], mutableCopyArray[1], [mutableCopyArray[1] class]);
    NSLog(@"mutableCopyArray: %@", mutableCopyArray);
    array_p: 0x600002460740, class: __NSArrayI
    copyArray_p: 0x600002460740, class: __NSArrayI
    mutableCopyArray_p: 0x600002a124c0, class: __NSArrayM
    ======原对象=====
    arr[0]:12345-abc  object_p: 0x600002a12550, class: __NSCFString
    arr[1]:6789 object_p: 0x10d9c8038, class: __NSCFConstantString
    ======copy对象=====
    arr[0]:12345-abc object_p: 0x600002a12550, class: __NSCFString
    arr[1]:6789 object_p: 0x10d9c8038, class: __NSCFConstantString
    ======mutableCopy对象=====
    arr[0]:12345-abc object_p: 0x600002a12550, class: __NSCFString
    arr[1]:6789 object_p: 0x10d9c8038, class: __NSCFConstantString mutableCopyArray: (
       "12345-abc",
        6789,
        efg
    )

容器可变对象

  • 浅拷贝开辟新内存,数据不可变,容器类数据只拷贝指针
  • 深拷贝开辟新内存,数据可变,容器类数据只拷贝指针
    NSMutableString *str1 = [NSMutableString stringWithFormat:@"12345"];
    
    NSMutableArray *array = [NSMutableArray arrayWithObjects:str1, @"6789", nil];
    NSMutableArray *copyArray = [array copy];
    NSMutableArray *mutableCopyArray = [array mutableCopy];
    [str1 appendString:@"-abc"];
    //[copyArray addObject:@"efg"];
    [mutableCopyArray addObject:@"efg"];
    
    NSLog(@"array_p: %p, class: %@", array, [array class]);
    NSLog(@"copyArray_p: %p, class: %@", copyArray, [copyArray class]);
    NSLog(@"mutableCopyArray_p: %p, class: %@", mutableCopyArray, [mutableCopyArray class]);
    
    NSLog(@"======原对象=====");
    NSLog(@"arr[0]:%@  object_p: %p, class: %@", array[0], array[0], [array[0] class]);
    NSLog(@"arr[1]:%@ object_p: %p, class: %@", array[1], array[1], [array[1] class]);
    
    NSLog(@"======copy对象=====");
    NSLog(@"arr[0]:%@ object_p: %p, class: %@", copyArray[0], copyArray[0], [copyArray[0] class]);
    NSLog(@"arr[1]:%@ object_p: %p, class: %@", copyArray[1], copyArray[1], [copyArray[1] class]);
    
    NSLog(@"======mutableCopy对象=====");
    NSLog(@"arr[0]:%@ object_p: %p, class: %@", mutableCopyArray[0], mutableCopyArray[0], [mutableCopyArray[0] class]);
    NSLog(@"arr[1]:%@ object_p: %p, class: %@", mutableCopyArray[1], mutableCopyArray[1], [mutableCopyArray[1] class]);
    NSLog(@"mutableCopyArray: %@", mutableCopyArray);
    array_p: 0x600003f0b7b0, class: __NSArrayM
    copyArray_p: 0x60000311dd60, class: __NSArrayI
    mutableCopyArray_p: 0x600003f0b450, class: __NSArrayM
    ======原对象=====
    arr[0]:12345-abc  object_p: 0x600003f0b5d0, class: __NSCFString
    arr[1]:6789 object_p: 0x107aa6038, class: __NSCFConstantString
    ======copy对象=====
    arr[0]:12345-abc object_p: 0x600003f0b5d0, class: __NSCFString
    arr[1]:6789 object_p: 0x107aa6038, class: __NSCFConstantString
    ======mutableCopy对象=====
    arr[0]:12345-abc object_p: 0x600003f0b5d0, class: __NSCFString
    arr[1]:6789 object_p: 0x107aa6038, class: __NSCFConstantString
    mutableCopyArray: (
    "12345-abc",
    6789,
    efg
    )

完全深拷贝

使用归档解档的方法

    NSMutableString *str1 = [NSMutableString    stringWithFormat:@"非容器可变对象"];
    NSArray *array = [NSArray arrayWithObjects:str1, @"非容器不可变对象", nil];
    
    NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithArray:array copyItems:YES];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:mutableArray requiringSecureCoding:YES error:nil];
    NSMutableArray *newMutableArray = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSMutableArray class] fromData:data error:nil];

    NSLog(@"===原对象===");
    NSLog(@"array[0] : %p, array[1] : %p", array[0], array[1]);
    
    NSLog(@"===新对象===");
    NSLog(@"mutableArray[0] : %p, mutableArray[1] : %p", mutableArray[0], mutableArray[1]);
    
    NSLog(@"===完全拷贝对象===");
    NSLog(@"newMutableArray[0] : %p, newMutableArray[1] : %p", newMutableArray[0], newMutableArray[1]);

如果是自定义类对象 需要遵循

@interface TestModel : NSObject<NSSecureCoding>
@property (nonatomic, strong) NSString *name;
@end


@implementation TestModel
+ (BOOL)supportsSecureCoding{
    return YES;
}

- (void)encodeWithCoder:(nonnull NSCoder *)coder {
    [coder encodeObject:self.name forKey:@"name"];
}

- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {
    self.name = [coder decodeObjectForKey:@"name"];
    return self;
}

@end

    TestModel *model = [[TestModel alloc] init];
    model.name = @"tianya";
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:model requiringSecureCoding:YES error:nil];
    TestModel *model1 = [NSKeyedUnarchiver unarchivedObjectOfClass:[TestModel class] fromData:data error:nil];
    NSLog(@"model = %@, model1 = %@",model, model1);

自定义对象拷贝

自定义对象, 需要我们去遵循 、 其实现方法我们可以根据自己的需要去填写

@interface TestModel : NSObject <NSMutableCopying, NSCopying>
@property (nonatomic, copy) NSString *name;
@end

@implementation TestModel
-(id)mutableCopyWithZone:(NSZone *)zone{
    TestModel *model = [[[self class] allocWithZone:zone] init];
    model->_name = [_name mutableCopy];
    return model;
}

- (nonnull id)copyWithZone:(nullable NSZone *)zone {
    return self;
}
@end

参考资料

www.jianshu.com/p/33f175d97…

www.jianshu.com/p/5df570135…

blog.csdn.net/hanhailong1…