2014-03-19 144 views
0

我对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];得到它的工作(正如你可以看到上面)任何人都可以照亮这个,我是否正确地做到这一点?

+0

如果你可以在超类中增加一些方法而不是在超类中添加相同的方法,例如initWithName和比自我= [超级initWithName:rootName]?只是一个想法不确定 –

回答

4

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

在设计良好的类层次结构和专门的框架类中,没有可用的源代码,您会发现大多数(如果不是所有的)实例变量都不能被子类访问,因为它隐藏了实现细节,并可能对基类做出未来更改。想象一下,如果基类需要在名称属性发生变化时进行验证 - 如果子类可以直接分配给伊娃,他们将绕过添加到伊娃设置方法的检查。

PS:我找到点符号的眼睛友好:

这很容易:关于 “不将消息发送到self到了init/dealloc的” 规则

self.name = rootName; 

UPDATE通过重新设计类以避免在其init方法中使用非必要参数而避免。这个子类的清洁器版本是:

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

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

+0

那么说你不应该在任何'init'方法中访问'self'的“规则”是什么? – Lance

+0

这是一个好点兰斯,这就是为什么我开始尝试使用_name的道路我会猜测在这种情况下它可以使用自我。 – fuzzygoat

+0

谢谢Steffen,这就是我的想法,但我只想得到一些确认,非常感谢。 – fuzzygoat