iOS学习之彻底搞清楚copy和mutableCopy

copy和mutableCopy其实比较容易理解。容易让人困惑的是,浅拷贝和深拷贝。

先说一下copy和mutableCopy。

copy,顾名思义是拷贝,复制的意思,是根据源对象,创建副本的过程。copy的目的是,在改变源对象的时候,副本对象的值不发生变化(反之亦然)。

在Objective-C中,对象要使用copy和mutableCopy,需要分别实现NSCopying协议和NSMutableCopying协议,以及copyWithZone方法和mutableCopyWithZone方法。

copy和mutableCopy的区别:

1、产生副本对象的类型不一样,copy产生的副本对象是不可变类型,比如经常用到的NSString,NSArray,NSDictionary等。mutableCopy产生的副本对象是可变类型,对应的是NSMutableString,NSMutableArray,NSMutableDictionary.

2、根据源对象的类型,以及副本对象的类型,决定是否产生新对象。也就是深拷贝和浅拷贝的区别。

具体来说分为4种情况:

1)、当源对象是不可变类型的时候,使用copy操作,得到的还是不可变类型副本,并且副本内存地址(指针)和源对象的内存地址是一样的,可以认为源对象和副本对象是同一对象,并没有产生新对象,相当于是执行了一次retain操作,这样的copy操作,叫做浅拷贝,也有人叫指针拷贝;

2)、当源对象是可变类型的时候,使用copy操作得到的是不可变类型副本。类型不一样,内存地址也肯定不一样,即在内存中分配了新的地址空间,产生了新的对象。虽然内存地址不一样,但两者的内容是一样的,这样的copy操作,叫做深拷贝,也有人这叫做内容拷贝;

3)、当源对象是不可变类型,使用mutableCopy操作,得到的副本对象是可变类型。一个可变,一个不可变,类型不一样,内存地址也不一样,产生了新的对象,所以也是深拷贝;

4)、当源对象是可变类型,使用mutableCopy操作,得到的副本对象是可变类型。这个时候源对象和副本对象的内存地址是否一样?是否产生了新的对象?上面提到过,使用复制的目的是,改变源对象,副本对象的内容不跟着改变,根据这个原则,两个可变类型对象,要想一个改变不影响另外一个,只能是两个不同的对象,指向不同的内存地址。所以,当源对象是可变类型,使用mutableCopy操作,得到的副本对象是可变类型,这个副本是新的对象,也是深拷贝;


PS:容器对象(NSArray)不管是copy和mutableCopy,容器中的元素都是指针拷贝,即浅拷贝。

你可能感兴趣的:(iOS学习之彻底搞清楚copy和mutableCopy)