protocol / POP issues: error: 'self' used before chaining to another self.init requirement:

protocol / POP issues: error: 'self' used before chaining to another self.init requirement:

尝试在 class 初始化期间使用此函数,因此我可以将类型名称 auto-added 添加到标题中:

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!)

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

error: 'self' used before chaining to another self.init requirement:

//
// 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!)

感谢任何解决方案或解决方法!

就像在您的继承示例中一样,您需要链接到另一个初始化程序才能使用 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)
}