澄清:问题不是关于mutable和immutable,而是关于调用super创建正确类的实例。我没想过在基类中使用[[self class] alloc]
,这似乎解决了我的问题。如果没有更好的结果,我会在接下来的几个小时内接受anser:)
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。
文档的含义是什么,真的吗?我该如何实现呢?
答案 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%是更好的方法。