oc学习笔记——深浅拷贝

深浅拷贝

1.定义

浅拷贝:浅拷贝就是创建一个新对象,该对象与原始对象共享内部数据的引用。也就是说,浅拷贝就是创建一个存放与复制对象相同地址的指针变量,也称为指针拷贝

深拷贝:深拷贝是指创建一个新对象,并复制原始对象及其引用的所有数据。深复制会递归地复制对象的所有内容,包括对象所引用的其他对象。这样,原始对象和副本对象拥有独立的内存空间,彼此之间的修改互不影响。也就是说深拷贝创建了一个与被复制的对象的值完全相同的对象,但是他们的地址是不同的,也称为内容拷贝

2.可变与非可变类的copy与mutable copy

其实有关容器类和非容器类,他们的深浅拷贝都是一样的,总结下来就是不可变类copy是浅拷贝,mutablecopy是深拷贝,可变类copy和mutablecopy都是深拷贝。
在这里插入图片描述

这是非容器类的深浅拷贝对比,运行结果如下:

在这里插入图片描述

容器类的如下:

在这里插入图片描述
在这里插入图片描述

可变类不可变类
copy深拷贝浅拷贝
mutablecopy深拷贝深拷贝

3.容器类里的元素都是浅拷贝

虽然对容器类进行copy或者mutablecopy操作与非容器类相同,但对于容器类的元素,都是浅拷贝

在这里插入图片描述

在这里插入图片描述

由以上可见容器类中的元素在拷贝后地址都相同,也就意味着都是浅拷贝。

4.自定义类的深浅拷贝

有关于自定义类,对于这个类本身,无论copy还是mutablecopy都是深拷贝,但是对于类中指针类型的属性,如果使用=或者copy,那么该属性是浅拷贝,如果调用mutablecopy方法,那么该属性是深拷贝。注意⚠️:想要对自定义类调用copy或者mutablecopy时,要遵守NScopying或者NSMutableCopying协议,重写copywithzone或者mutablecopywithzone方法。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这里重写copywithzone时,对字符串属性用的是=,重写mutablecopywithzone时,对字符串属性用的是muatblecopy。代码运行结果如下:

在这里插入图片描述

也就意味着,对于自定义类,对该类拷贝都是深拷贝,但是类中指针类型的属性深浅拷贝由重写的方法决定

5.属性关键字copy与strong

在定义属性时,可以选择copy或者strong关键字来修饰,选择copy还是strong有一些区别。
在这里插入图片描述
在这里插入图片描述

这里代码中的export属性就是用copy修饰的,当试图用appendString去修改时,会看到程序编译出现了错误,提示:“试图修改一个不可修改的变量”。其实是因为copy关键字,就相当于在对属性赋值的时候调用了一次copy方法,那么得到的属性就已经变成不可变类型了,自然就不能调用方法修改了。所以,在选择关键字时,一般可变类使用strong,不可变类使用copy。

6.容器类对象的完全深拷贝

对于容器类对象,之前提到容器类中的元素全都是浅拷贝,那么如何实现容器类对象的完全深拷贝呢?有如下三种方法

copyitems

copyitems是oc提供的一种初始化方法,当可以直接通过该方法对容器进行完全深拷贝

copyitems用于创建一个新的数组,并对数组中的元素进行拷贝。该方法会遍历原始数组的每个元素,并对每个元素执行 copy 操作,然后将拷贝后的元素添加到新的数组中。

在这里插入图片描述
在这里插入图片描述

但是,当容器类的元素是指针类型(比如字符串、容器)时,就无法实现完全深拷贝。

在这里插入图片描述
在这里插入图片描述

递归复制属性

那么遇到指针类型的元素,或者属性时,我们就要递归的复制属性,对每一个属性进行深拷贝,就可以实现完全深拷贝。

也就是上文提到在自定义类中对字符串等这样的指针变量调用mutablecopy方法进行深拷贝,由于上文已经阐述过,这里就不用代码演示了

解档与归档

这个方法笔者暂时还没有深入学习,以后再来补充

  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Objective-C 中,拷贝(Deep Copy)和浅拷贝(Shallow Copy)是用于复制对象的两种不同方式。 浅拷贝是指创建一个新的对象,该对象与原始对象共享数据的内存地址。换句话说,新对象只是原始对象的一个引用,对新对象的修改也会影响原始对象。在 Objective-C 中,可以使用 `copy` 方法来执行浅拷贝拷贝是指创建一个新的对象,并且复制原始对象的所有数据。这意味着新对象有自己的内存地址,对新对象的修改不会影响原始对象。在 Objective-C 中,可以使用 `mutableCopy` 方法来执行拷贝。 需要注意的是,拷贝只会复制对象本身,而不会递归地复制对象所包含的其他对象。如果需要对对象的所有数据进行递归复制,可以通过实现 NSCopying 协议来自定义拷贝操作。 下面是一个示例代码,演示了如何执行浅拷贝拷贝: ```objective-c #import <Foundation/Foundation.h> @interface Person : NSObject <NSCopying> @property (nonatomic, copy) NSString *name; @end @implementation Person - (instancetype)copyWithZone:(NSZone *)zone { Person *copy = [[Person allocWithZone:zone] init]; copy.name = self.name; return copy; } @end int main(int argc, const char * argv[]) { @autoreleasepool { Person *person1 = [[Person alloc] init]; person1.name = @"John"; // 浅拷贝 Person *person2 = [person1 copy]; NSLog(@"person1: %@, person2: %@", person1.name, person2.name); // 输出:person1: John, person2: John // 拷贝 Person *person3 = [person1 mutableCopy]; person3.name = @"Emily"; NSLog(@"person1: %@, person3: %@", person1.name, person3.name); // 输出:person1: John, person3: Emily } return 0; } ``` 在上面的示例中,使用 `copy` 方法执行了浅拷贝操作,`mutableCopy` 方法执行了拷贝操作。注意,为了实现拷贝,我们在 `Person` 类中遵循了 NSCopying 协议,并重写了 `copyWithZone:` 方法来自定义拷贝操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值