在Objective-C中继承属性和合成

时间:2012-10-02 23:56:55

标签: objective-c ios inheritance

我有以下类和子类:

@interface NSHigh : NSObject
@property (nonatomic, strong) NSArray *array;
@end
@implementation NSHigh
-(NSArray*)array
{
    _array = [[NSArray alloc] init];
    return _array;
}
@end

@interface NSLow : NSHigh
@end
@implementation NSLow
/* synthesizing makes the assertion FAIL. NO synthesizing makes the assertion PASS */
@synthesize array;
@end

然后我在某处运行此代码:

NSLow *low = [[NSLow alloc] init];
assert(low.array);

所以,显然,如果在子类NSLow中我合成了数组属性,那么来自超类的getter不会被调用,并且断言失败。

如果我不合成,则调用超类getter,并且断言通过。

  1. 为什么会这样?
  2. 如何在不调用NSLow的情况下每次都访问self.array子类中的数组实例变量?

1 个答案:

答案 0 :(得分:8)

@synthesize中的

NSLow将创建以下getter:

- (NSArray *)array {
    return _array;
}

因此,您的数组永远不会被初始化,并且会返回nil

您通常不应将@synthesize用于在超类中声明的@properties

此外,您不应该像NSHigh中那样实现一个getter。如果你想懒洋洋地初始化那个数组,你应该这样做:

- (NSArray *)array {
    if (!_array) {
        _array = [[NSArray alloc] init];
    }
    return _array;
}

最后,您不应该使用NS前缀。

修改

如果您想直接访问子类中的ivar,可以在标题中明确声明它,如下所示:

@interface NSHigh : NSObject {
    NSArray *_array;
}
@property (nonatomic, strong) NSArray *array;
@end

这样您也可以访问子类中的ivar。