是否可以在子类中重新声明私有ivars以使其可访问?

时间:2013-06-19 09:27:43

标签: objective-c cocoa-touch cocoa subclass foundation

当子类化在.h文件中列出私有ivars的Apple类时,可以在子类.m文件中的类扩展@interface中重新声明自己子类中的那些ivar,以使它们可以被子类访问执行?

2 个答案:

答案 0 :(得分:8)

您必须记住,在子类中声明实例变量不会重新声明具有相同名称的现有超类实例变量,无论声称的重新声明是在公共接口还是类扩展中。即使您使用相同的名称,也是一个不同的实例变量

你可以自己尝试一下。例如:

@interface Base : NSObject {
@private
    int _number;
}
@end

@implementation Base
- (id)init { self = [super init]; if (self) _number = 10; return self; }
- (void)logNumber { printf("base = %d\n", _number); }
@end

@interface Derived : Base
@end

@interface Derived () {
    int _number;
}
@end

@implementation Derived
- (id)init { self = [super init]; if (self) _number = 20; return self; }
- (void)logNumberDerived { printf("derived = %d\n", _number); }
@end

int main(void) {
    Derived *o = [Derived new];
    [o logNumber];
    [o logNumberDerived];
    return 0;
}

输出:

base = 10
derived = 20

因为超类中的_number与子类(扩展名)中的_number不同。如果使用nm -a检查二进制输出中的符号,您会注意到编译器生成两个不同的符号:

s _OBJC_IVAR_$_Base._number
s _OBJC_IVAR_$_Derived._number

答案 1 :(得分:3)

我在这里找到了与我自己完全匹配的答案:http://lists.apple.com/archives/cocoa-dev/2007/Feb/msg00939.html

  

如果他们将其设为@private而不是@protected则必须假设   这是有原因的。那个原因当然可以就是这样   在你知道一个很好的理由之前,做一切@private是明智的   不要......

     

那就是说,它可以非常明确 可以访问它   直接,即使技术上可行。

     

安全的做法是在你自己的课堂上重新做一切   请求超类的维护者公开   您需要在公共/受保护的界面中使用的功能。