mutableCopyWithZone令人困惑的要求?

时间:2013-05-29 06:35:07

标签: objective-c nscopying nsmutablecopying

澄清:问题不是关于mutable和immutable,而是关于调用super创建正确类的实例。我没想过在基类中使用[[self class] alloc],这似乎解决了我的问题。如果没有更好的结果,我会在接下来的几个小时内接受anser:)


The Apple spec says:

If a subclass inherits NSMutableCopying from its superclass and declares
additional instance variables, the subclass has to override mutableCopyWithZone:
to properly handle its own instance variables, invoking the superclass’s
implementation first.

这很令人困惑。考虑

@interface Base : NSObject<NSMutableCopying>
@property (nonatomic, assign) NSInteger value ;
@end
@implementation Base
...
@end


@interface Derived : Base<NSMutableCopying>
@property (nonatomic, assign) NSInteger value2 ;
@end

@implementation Derived

- (id) mutableCopyWithZone: (NSZone *) zone {
    // Huh ???
    Derived * derived = [super mutableCopyWithZone: zone] ;
    ...
    // Huh ??????
    derived.value2 = self.value2 ;
    return derived ;
}
...
@end

如果我遵循规范,我只是不明白这段代码是如何正确的。

当对[super mutableCopyWithZone: zone]的调用返回时,我希望基类只为自己的ivars分配了足够的空间。它无法判断Derived实例需要更多空间来存放自己的ivars。

文档的含义是什么,真的吗?我该如何实现呢?

1 个答案:

答案 0 :(得分:4)

super只会改变调度方式(静态而不是动态)。但它不会改变接收器,尤其是它没有向上倾斜。 In -mutableCopyWithZone :(超级)self仍然指向派生类的实例对象。

如果超级方法(或超级超级方法等)没有以适当的方式实现对象创建,则可能出现问题:

copy = [[BaseClass alloc] init]; // Wrong, an instance of the base class is created

copy = [[[self class] alloc] init]; // Correct, an instance of [self class] == DerivedClass is created

使用第二种方法,您将获得一个派生类的实例,其中包含完整的内存。

结论:如果BaseClass正确实现其-mutableCopyWithZone:以这种方式实现它。否则,您没有其他更改,然后创建自己的副本并初始化它。

在我的书中,我总是写道,没有理由在课堂内使用班级名称。使用[self class](在实例方法中)和self(在类方法中)99%是更好的方法。