加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

objective-c – 在copyWithZone中为可变子类返回[self retain]是

发布时间:2020-12-16 05:06:58 所属栏目:百科 来源:网络整理
导读:人们常常会读到,不可变类可以通过以下方式非常有效地实现copyWithZone: - (id) copyWithZone:(NSZone*)zone{ return [self retain];} 实施背后的想法是显而易见的: 原始和副本都是不可变的实例,它们将始终具有完全相同的内容,因此,为什么不通过保留原始文
人们常常会读到,不可变类可以通过以下方式非常有效地实现copyWithZone:
- (id) copyWithZone:(NSZone*)zone
{
    return [self retain];
}

实施背后的想法是显而易见的:
原始和副本都是不可变的实例,它们将始终具有完全相同的内容,因此,为什么不通过保留原始文件来指向同一存储,并避免复制的开销.

但是,如果存在可变子类会发生什么?
使用干净的体系结构,子类不必关心其基类的实现细节,可变子类应该可以通过这种方式实现copyWithZone:

- (id) copyWithZone:(NSZone*)zone
{
    MyClass* myCopy = [super copyWithZone:zone];
    myCopy->myMember = [myMember copyWithZone:zone];
    return myCopy;
}

但这对于copyWithZone的上述超类实现意味着什么呢?
子类是可变的,所以虽然副本仍然是不可变的,但是原来现在是可变的,但是由于超类实现的子类copyWithZone在自身的保留实例上运行:self和myCopy都指向同一个实例,所以如果我以后更改mutableOriginal.myMember的值,然后这也将更改immutableCopy.myMember,这是完全错误的.

那么不可变的类应该以下面的方式更好地实现copyWithZone?

- (id) copyWithZone:(NSZone*)zone
{
    if([[self class] isMemberOfClass:[MyBaseClass class]])
        return [self retain];
    else
    {
        MyBaseClass* myCopy = [[self alloc] init];
        myCopy->myBaseMember = [myBaseMember copyWithZone:zone];
        return myCopy;
    }
}

解决方法

您最好的选择是在不可变的超类中使用initWithMyImmutableObject初始化器.然后你的子类可以用它来实现NSCopying
- (id) copyWithZone:(NSZone*)zone {
    return [[[self superclass] alloc] initWithMyImmutableObject:self]
}

这样,属性的实际复制是在超类的方法中完成的,该方法可以访问需要复制的所有私有成员.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读