初始化器不会覆盖其超类中的指定初始化器

Initializer does not override a designated initializer from its superclass

所以我刚刚升级到 Xcode 6.3 Beta 3 并且出现了很多与以下相关的错误:

Initializer does not override a designated initializer from its superclass.

override init() {
    super.init()
}

例如这是一个 UIButton class:

class CustomButton: UIButton {

    var target: AnyObject!
    var selector: Selector!
    var action: (() -> Void)!

    override init() { // Initializer does not override a designated initializer from its superclass
        super.init() // Must call a designated initializer of the superclass 'UIButton'
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }
}

这是我的 UIViewController classes:

class CustomAlertView: UIViewController {

    required init(coder aDecoder: NSCoder) {
        fatalError("NSCoding not supported")
    }

    required override init() { // Initializer does not override a designated initializer from its superclass
        super.init() // Must call a designated initializer of the superclass 'UIViewController'
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }
}

我最近弄明白了这个问题,我想解释一下问题出在哪里。最初在 Apple Developer forums.

上回答

似乎 Swift 改变了初始化器依赖检查或导入初始化器的策略。

现在,如果您的初始化程序如图所示,处理 Xcode 6.3 Beta 2 和 Beta 3 的一种方法是删除所有初始化程序定义:

class CustomButton: UIButton {

    var target: AnyObject!
    var selector: Selector!
    var action: (() -> Void)!    
}

class CustomAlertView: UIViewController {

}

没有定义任何指定的初始值设定项,类继承它们的父级类的所有初始值设定项。

一个非常简单的修复,但一个大陷阱让我难住了一段时间。

根据 Apple 文档 here,您要覆盖的是便利初始化程序。因此,为了使您的初始化程序正常工作,您必须将方法更改为

override convenience init() {
    super.init()
}

你可以这样做,或者如果除了调用超类初始化器之外你没有真正使用初始化器,则删除它。

我的解决方案是快速修复,但我认为比 Apple 在发行说明中的​​目的要简单。如需更多信息,请在此处搜索 19775924 http://adcdownload.apple.com//Developer_Tools/Xcode_6.3_beta_3/Xcode_6.3_beta_3_Release_Notes.pdf。 Apple 所说的是您创建一个 Objective-C 文件并扩展它(必须将它添加到头文件和所有文件中)并且它在 "Known Issues in Xcode 6.3 beta 3" 上,所以我认为很容易做我所做的:

这就是我为 UIButton 修复它的方法:

class CustomButton : UIButton {
    init() {
        super.init(frame: CGRectZero)
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

这是我的 ViewController 之一(如果不需要,请删除 public):

public class GenericViewController: UIViewController {
    public init() {
        super.init(nibName: nil, bundle: nil)
    }

    required public init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

我不使用 IB,所以我也有 UIView,因为我确实将视图与 viewController 分开(如果不需要,请删除 public):

public class GenericMenuView: UIView {
    public init() {
        super.init(frame: CGRectZero)
    }

    public required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

我在视图中特别需要这个,因为我有一个 setupViews 方法,我在初始化时调用的所有子 classes 中重写该方法。使用 AutoLayout 我不需要任何框架(所以我不使用 frame 参数覆盖 init)。

所以看来你必须放弃 override。哦!并确保不要调用 self.init() 或 class 永远不会初始化(并且它会在一些内部超时后崩溃)。

我认为这比看起来容易得多。

对于 SKSpriteNode,我是这样做的:

override init() {
    let texture = SKTexture(imageNamed: "bgTile")
    super.init(texture: texture, color: nil, size: texture.size())
}

问题是 init() 不是 SKSpriteNode 的指定初始化程序。所以我只是将其更改为:

override init(texture: SKTexture!, color: UIColor!, size: CGSize) {
    let texture = SKTexture(imageNamed: "bgTile")
    super.init(texture: texture, color: nil, size: texture.size())
}

现在可以正常使用了。

错误解决方案:覆盖 init(coder aDecoder: NSCoder!) 未按预期工作 - Swift

这对我有用,试试这个,注意:你必须唤醒笔尖

override func awakeFromNib() {

     super.awakeFromNib()
    // Initialisation code

}