在子类中设置超类的属性?

时间:2014-03-19 13:12:18

标签: ios objective-c sprite-kit sknode

我正在研究名为SKNode

UtilityNode的子类
@implementation UtilityNode

- (id)initWithName:(NSString *)rootName {
    self = [super init];
    if(self) {
        [self setName:rootName]; // ?
    }
    return self;
}

@end

我正在为新节点initWithName:设置一个指定的初始化程序,我在创建新的子类时尝试初始化超类SKNode的名称。我的印象是我可以写_name = rootName;,但_name被标记为未声明。我已经通过使用[self setName:rootName];让它工作了(正如你在上面看到的那样)任何人都可以对此有所了解,我是否正确地做到了这一点?

1 个答案:

答案 0 :(得分:4)

这是对的。 _name实例变量可能被声明为@private(自动合成属性的默认值),因此子类无法访问它。

在精心设计的类层次结构中,特别是没有源代码可用的框架类,您会发现子类无法访问大多数(如果不是全部)实例变量,因为它隐藏了实现细节,并且可以对将来的基类进行更改。想象一下,如果基类需要在更改时验证name属性 - 如果子类可以直接分配给ivar,它们将绕过添加到ivar setter方法的检查。

PS:我觉得眼睛上的点符号比较友好:

 self.name = rootName;
关于"不要在init / dealloc"中向self发送消息的

更新规则:

通过重新设计类以在其init方法中不采用非必要参数,可以轻松避免这种情况。这个子类的更清洁版本是:

UtilityNode* un = [UtilityNode node];
un.name = @"some name";

如果节点绝对需要设置参数,则在要求名称有效的方法中通过NSAssert警告用户。