0

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


苹果规范说:

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。

文档的真正含义是什么?我应该如何实现这个?

4

1 回答 1

4

super 只改变了调度方式(静态而不是动态)。但它不会改变接收器,尤其是。它没有上扬。在 -mutableCopyWithZone: (super) 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

使用第二种方法,您可以获得一个派生类的实例,它的 ivars 具有完整的内存。

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

在我的书中,我总是写,几乎没有理由在类中使用类名。使用 [self class](在实例方法中)和 self(在类方法中)是 99% 更好的方法。

于 2013-05-29T07:27:55.853 回答