【问题标题】:Objective-C - object is init'd using its supers custom init, how can you call your own init logic?Objective-C - 使用它的超级自定义初始化来初始化对象,你怎么能调用你自己的初始化逻辑?
【发布时间】:2013-02-06 19:18:03
【问题描述】:

我正在浏览一本 cocos2D 书籍,并且正在尝试初始化 Radar Dish 对象。动画是在 initAnimations 方法中设置的(在 init 方法中调用),但是从不调用 init 方法。在 GameLayer.m 中,他们使用 createObjectOfType 方法,该方法调用:

RadarDish *radarDish = [[RadarDish alloc] initWithSpriteFrameName:@"radar_1.png"];

所以 initWithSpriteFrameName 是 RadarDish 的超类的 init,它设置了 Radar Dish。那么 RadarDish.m 的 init 什么时候会被调用?这导致我的程序崩溃,因为动画从未在 init 中设置。

【问题讨论】:

  • initWithSpriteFrameName 是如何定义的?它叫init吗?

标签: objective-c cocos2d-iphone kobold2d


【解决方案1】:

您需要在任何子类中覆盖initWithSpriteFrameName:,包括RadarDish,这需要自己的初始化步骤。在该方法中,您需要调用超类的designated initializer,然后继续处理子类的特定需求,如下所示:

- (id)initWithSpritFrameName: (NSString *)frameName
{
    self = [super initWithSpriteFrameName:frameName];
    if( !self ) return nil;

    [self initAnimations];    // As long as initAnimations doesn't also call a
                              // superclass's initializer!
    // Other setup...

    return self;
}

现在[[RadarDish alloc] initWithSpriteFrameName:...] 将使用此实现,确保为您的对象设置动画。

您还应该更改 initAnimations 的名称,因为 Cocoa 约定只有实际的实例初始化器——采用“原始”实例并完全准备实例的方法——应该以 init 开头。称它为setUpAnimations 或类似名称。

【讨论】:

  • 是否可以在上面的代码中调用[self init],因为调用了相当多的变量和方法,还是在同一个类中调用两个init方法会搞砸?
  • "Multiple initializers"。您可以链接初始化方法,但只有最后一个可以调用 super 的初始化方法,理想情况下只有那个应该做任何工作;其他人应该简单地打电话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多