objective-c – 在copyWithZone中为可变子类返回[self retain]是否真的安全/好主意?

前端之家收集整理的这篇文章主要介绍了objective-c – 在copyWithZone中为可变子类返回[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]
}

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

猜你在找的C&C++相关文章