iOS - 浅复制和深复制

在objc里,对象的复制方式有两种:浅复制和深复制。浅复制是指针的复制,也就是地址拷贝。深复制是对象的复制,这种复制方式会拷贝一个新的对象,并将指针指向该对象。

并不是所有objc对象都支持浅复制和深复制。浅复制(copy)和深复制(mutableCopy) 分别是通过 NSCopying 和 NSMutableCopying 协议实现的。通过查看对象具体实现了哪一个协议,可以判断能否使用 copy: 或 mutableCopy: 函数。

基础对象

如果我们查看NSString的结构,我们可以看到 NSString 实现了上述两条协议,因此我们可以判断 NSString 可以通过 copy: 和 mutableCopy: 进行复制。

我们对一个 NSString 对象进行 copy 和 mutableCopy:

NSString *str = @"sbxfc";
NSString *strCopy = [str copy];
NSString *strMCopy = [str mutableCopy];

通过断点,并在控制台上输出对象信息,我们可以看到 strCopy 和 str 指向的是同一个内存地址,而 strMCopy 指向了另外一个地址。这就是说 strCopy 进行了浅复制而 strMCopy 进行了深复制:

集合

对于集合对象,我们也用上述方式进行观察:

NSArray实现了NSCopying和NSMutableCopying协议,对NSArray进行测试:

 NSArray *array = @[@"sbxfc",@17];
 NSArray *arrayCopy = [array copy];
 NSArray *arrayMCopy = [array mutableCopy];

和预期结果一致:

但是,对于集合对象我们更关心的是其内部元素有没有发生变化(浅复制和深复制)。

PS,如果你多查看几个objc对象结构,你会发现有许多对象并没有实现 NSMutableCopying 协议,也就是说许多对象不能进行深拷贝。那么当集合进行复制时,其内部元素是不能完成深复制的。

当集合对象进行复制时,里面的元素执行的是指针拷贝,也就是浅复制。
再次验证一下:

可以看出字符串 @“sbxfc” 的地址是一样的。

Comments