iOS Develop Daily Tips

iOS Daily Tip - 深拷贝与浅拷贝

2018-03-09  本文已影响4人  过客又见过客

浅拷贝,实际上是指针拷贝。对一个对象进行浅拷贝,相当于对指向该对象的指针进行复制,生成了一个新的指向该对象的指针,也就是说指向该对象的指针又增加了一个。因为指向的是同一个对象,也就是同一块内存地址,所以通过任意一个指针修改对象的时候,其实操作的都是同一块内存地址。而当该对象销毁时,作为指向该对象的指针都应该随之而置空,不然就成了我们常说的野指针了。具体示例图如下:

屏幕快照 2018-03-09 下午10.44.36.png

深拷贝,才是真正的对一个对象进行拷贝,也就是说如果对一个对象进行深拷贝的话,就会产生一个新的该对象类型的对象,相当于new了一个新的实例,拥有自己的独立的内存空间,当然也会随之而生成一个新的指针指向该新的实例。因为是两个独立的实例对象,各自拥有自己独立的内存空间,所以对其中任意一个对象修改或者销毁,都不会影响到另外一个对象。具体示例图如下:

屏幕快照 2018-03-09 下午10.46.39.png

实现深拷贝需要实现NSCopying协议,实现- (id)copyWithZone:(NSZone *)zone方法。这里需要注意的是如果父类实现了该方法,而子类同样重写了该方法,该如何处理。注意代码注释部分。下面看代码实例:

#import <Foundation/Foundation.h>

@interface Person : NSObject<NSCopying>
@property (nonatomic, copy) NSString *name;
- (id)copyWithZone:(NSZone *)zone;
@end

@interface Student : Person
@property (nonatomic, copy) NSString *schoolName;
@end

.m文件内容如下,注意代码里面的注释,解释的很清楚了:

#import "Person.h"

@implementation Person

- (id)copyWithZone:(NSZone *)zone
{
    //方法1
//    Person *per = [[Person allocWithZone:zone] init];//方法1
    //方法2
//    Person *per = [[Person alloc] init];
    //方法3,使用的是[self class],是动态的。建议无论是否存在子类,都使用该方法。
    //如果子类重写了该方法,必须使用方法3,不然会crash。
    Person *per = [[[self class] allocWithZone:zone] init];
    per.name = self.name;
    return per;
}

@end

@implementation Student

- (id)copyWithZone:(NSZone *)zone
{
    //父类必须是使用方法3,实现copyWithZone。
    Student *stu = [super copyWithZone:zone];
    stu.schoolName = self.schoolName;
    return stu;
}
@end

可加群一起交流共同学习:801216530。

上一篇 下一篇

猜你喜欢

热点阅读