Objective-C中的copy协议

NSObject对象是否可以copy自己

NSObject类没有实现NSCopying或者NSMutableCopying协议,但是却有copy以及mutableCopy实例方法。然而,如果用NSObject对象直接调用其copy或者mutableCopy方法,会报错。也就是说,NSObject对象无法copy自己。

既然NSObject类没有实现copy协议,那为什么还要有对应的copy和mutableCopy方法呢?

因为NSObject类的copy和mutableCopy方法里面分别都会调用copyWithZone以及mutableCopyWithZone,那么所有继承自NSObject类并且实现NSCopying或者NSMutableCopying协议的类的拷贝行为,都可以简化为调用copy或者mutableCopy方法。

 

实现copy协议时,何时需要调用[super copyWithZone:zone]

1 类直接继承自NSObject,无需调用[super copyWithZone:zone]

复制代码
@interface X : NSObject <NSCopying>

@property (assign, nonatomic) NSInteger i;

@end

@implementation X

- (id)copyWithZone:(NSZone *)zone {
    X *x = [[[self class] alloc] init]; //没有调用[super copyWithZone:zone]
    x.i = self.i;
    
    return x;
}
复制代码

类X直接继承自NSObject,由于NSObject没有实现copy协议,因此如果调用[super copyWithZone:zone]编译器会报错:

No visible @interface for 'NSObject' declares the selector 'copyWithZone:'

 

2 父类实现了copy协议,子类也实现了copy协议,子类需要调用[super copyWithZone:zone]

复制代码
@interface Y : X <NSCopying>

@property (assign, nonatomic) NSInteger j;


@end

@implementation Y


- (id)copyWithZone:(NSZone *)zone {
    Y *y = [super copyWithZone:zone]; //子类调用[super copyWithZone:zone]
    y.j = self.j;

    return y;
}


@end
复制代码

子类通过调用[super copyWithZone:zone]方法来分配内存,并且拷贝父类中的实例变量,子类自己的实例变量需要自己拷贝

 

3 父类没有实现copy协议,子类实现了copy协议,子类无需调用[super copyWithZone:zone]

如果上面的例子中类X没有实现copy协议,而子类Y实现了copy协议,这种情况类似与情形1,子类Y无需调用[super copyWithZone:zone]

- (id)copyWithZone:(NSZone *)zone {
    Y *y = [[[self class] alloc] init]; //子类无需调用[super copyWithZone:zone]
    y.i = self.i;
    y.j = self.j;

    return y;
}

但是这种时候子类需要自己copy父类中的实例变量。

 

为何在copyWithZone方法中要调用[[[self class] alloc] init]来分配内存

在上面的情形2中,子类Y继承子父类X,如果父类X的copyWithZone方法使用:

[[X alloc] init];

来分配内存,那么在子类Y copy的时候就会出现内存分配的问题。

因为在子类Y的copyWithZone的方法里面调用会调用父类[super copyWithZone:zone]方法,而父类中[[X alloc] init]创建的对象分配的内存大小和类X的实例一样大,而这里是要拷贝Y,类Y继承了X的实例变量,同时也有自己的实例变量,所以类Y的实例所占用的内存明显比类X的实例大,因此,这里会导致内存分配错误。而父类X中如果使用[[[self class] alloc] init]来创建对象分配内存,在运行时self class就是类Y,这样保证了内存分配正确。

 

propery中的copy属性

这里只需记住,property的copy只会产生copyWithZone的调用,而不会产生mutableCopyWithZone的调用。

 

posted @   chaoguo1234  阅读(1208)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示