是否在所有init方法中都要求设置非可选的ivars?

时间:2014-06-18 15:17:49

标签: initialization sprite-kit swift subclassing

我试图创建一个SKSpriteNode子类。计划是让它在内部处理大部分设置,但令人讨厌的是,这似乎强制执行相当多的代码重复,特别是在设置非可选的ivars和常量时。

class TrollSpriteRegular : SKSpriteNode{
    let head : SKSpriteNode
    let body : SKSpriteNode

    init(){
        head = SKSpriteNode(color: SKColor.orangeColor(), size: CGSizeMake(60, 60))
        body = SKSpriteNode(color: SKColor.purpleColor(), size: CGSizeMake(40, 60))
        super.init()
    }

    // Desginated intiallizer
    init(texture: SKTexture!, color: UIColor!, size: CGSize) {
        head = SKSpriteNode(color: SKColor.orangeColor(), size: CGSizeMake(60, 60))
        body = SKSpriteNode(color: SKColor.purpleColor(), size: CGSizeMake(40, 60))
        super.init(texture: texture, color: color, size: size)
    }
}

如果我尝试从两个初始化器中的任何一个中删除头部或主体的创建,则会导致编译器错误,我无法构建。有没有办法避免这种情况,或者上面的模式可能不是特别快速友好?

我需要" init方法,只允许使用let trollSprite = TrollSpriteRegular()创建新实例。


编辑:好的,可以通过在声明它们时定义常量来简化上述内容。

class TrollSpriteRegular : SKSpriteNode{
    let head = SKSpriteNode(color: SKColor.orangeColor(), size: CGSizeMake(60, 60))
    let body = SKSpriteNode(color: SKColor.purpleColor(), size: CGSizeMake(40, 60))
...

但是,如果我添加一个应该通过init方法实际接收其值的变量,我将遇到同样的问题。 e.g:

let trollName : String

init(name :String){ 
    trollName = name
    super.init(texture: nil, color: nil, size: CGSizeZero)
}

这将迫使我在我自己的init(name:)和指定的初始化程序中定义trollName。哦,好吧。

2 个答案:

答案 0 :(得分:1)

考虑到非可选变量不能为零,这种行为是可以预期的。如果您正在寻找一种更简洁地完成所有这些操作的方法,您可以使用默认值(颜色和大小)内联初始化变量。然后,如果您碰巧有一个需要更改其中一个值的初始化程序,您可以直接更改精灵的颜色或大小属性的值。

class TrollSpriteRegular: SKSpriteNode {
    let head = SKSpriteNode(color: SKColor.orangeColor(), size: CGSizeMake(60.0, 60.0))
    let body = SKSpriteNode(color: SKColor.purpleColor(), size: CGSizeMake(40.0, 60.0))

    ...
}

答案 1 :(得分:1)

需要指定的初始化程序来初始化所有类的状态。在便捷初始化程序中,您可以将该责任委派给指定的初始化程序。

但是,在您的情况下,您似乎需要两个指定的初始值设定项。但由于这些变量不依赖于初始值设定项的任何输入值,因此您只需在其声明中定义它们的值即可。这是该类的重复性较低的版本:

class TrollSpriteRegular : SKSpriteNode {
    let head : SKSpriteNode = SKSpriteNode(color: SKColor.orangeColor(), size: CGSizeMake(60, 60))
    let body : SKSpriteNode = SKSpriteNode(color: SKColor.purpleColor(), size: CGSizeMake(40, 60))
}