协议/ POP问题:错误:在链接到另一个self.init要求之前使用'self':

时间:2017-03-14 00:40:06

标签: swift swift-protocols

尝试在类初始化期间使用此func,因此我可以将类型名称自动添加到标题中:

func getTypeOf(_ object: Any) -> String {  
  return String(describing: type(of: object)) + ": "
}

我在典型的继承设置中运行良好,但我正在努力切换到更多的POP / FP风格:

import SpriteKit

//
// OOP Demo:
//
class IGEoop: SKSpriteNode {

  init(title: String) {
    super.init(texture: nil, color: UIColor.blue, size: CGSize.zero)
    self.name = getTypeOf(self) + title
  }
  required init?(coder aDecoder: NSCoder) { fatalError() }
}

class PromptOOP: IGEoop {
}

// Works fine:
let zipOOP = PromptOOP(title: "hi oop")
print(zipOOP.name!)

这是我无法工作的块,并收到错误消息:

  

错误:在链接到另一个self.init要求之前使用'self':

//
// POP Demo:
//
protocol IGEpop { init(title: String) }
extension IGEpop where Self: SKSpriteNode {
  init(title: String) {
    // error: 'self' used before chaining to another self.init requirement:
    self.name = getTypeOf(self) + title
  }
}

class PromptPOP: SKSpriteNode, IGEpop {
  required init?(coder aDecoder: NSCoder) { fatalError() }
}

// Errars:
let zipPOP = PromptOOP(title: "hi pop")
print(zipPOP.name!)

任何解决方案或变通方法都很感激!

1 个答案:

答案 0 :(得分:2)

就像在继承示例中一样,您需要在能够使用self之前链接到另一个初始化器。因此,例如,我们可以链接到init(texture:color:size)

extension IGEpop where Self : SKSpriteNode {

    init(title: String) {
        self.init(texture: nil, color: .blue, size: .zero)
        self.name = getTypeOf(self) + title
    }
}

唯一的问题是PromptPOP 的实现是init(texture:color:size)。它定义了指定初始化程序init(aCoder:)的实现,因此它不会继承SKSpriteNode指定的初始化程序。

因此,您需要删除init(aCoder:)的实现,以便PromptPOP可以继承其超类'指定的初始化者,或提供init(texture:color:size)的实施 - 在这种情况下可以简单地链接到super

class PromptPOP : SKSpriteNode, IGEpop {
    required init?(coder aDecoder: NSCoder) { fatalError() }

    // note that I've marked the initialiser as being required, therefore ensuring
    // that it's available to call on any subclasses of PromptPOP.
    override required init(texture: SKTexture?, color: NSColor, size: CGSize) {
        super.init(texture: texture, color: color, size: size)
    }
}

尽管可能需要在协议扩展中添加用于协议要求的初始化程序,因此确保所有符合规范的类型在编译时实现它(否则你将会这样做)如果他们不这样做,就会收到运行时错误。

protocol IGEpop {
    init(title: String)
    init(texture: SKTexture?, color: NSColor, size: CGSize)
}