Initializer does not override a designated initial

2020-01-28 03:15发布

So I've just upgraded to Xcode 6.3 Beta 3 and a lot of error(s) are appearing relating to the following:

Initializer does not override a designated initializer from its superclass.

override init() {
    super.init()
}

For example this is a 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)
    }
}

This is one of my 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)
    }
}

5条回答
甜甜的少女心
2楼-- · 2020-01-28 03:27

Solution for Error : Override init(coder aDecoder: NSCoder!) not working like expected - Swift

This works for me , Try this, Note: u must awake nib

override func awakeFromNib() {

     super.awakeFromNib()
    // Initialisation code

}
查看更多
Rolldiameter
3楼-- · 2020-01-28 03:32

As per Apple documentation here, what you are overriding is a convenience initializer. So for your initializer to work, you will have to change the method to

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

You can either do that, or remove the initializer if you are not really using it except for calling the superclass initializer.

查看更多
Anthone
4楼-- · 2020-01-28 03:32

I recently figured this out and I'd like to explain what the problem was. Originally answered on the Apple Developer forums.

It seems Swift has changed the strategy for initializer dependency checking or for imporing initializers.

Now if your initializers' are as shown, one way to deal with both Xcode 6.3 Beta 2 and Beta 3 is to remove all initializer definitions:

class CustomButton: UIButton {

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

class CustomAlertView: UIViewController {

}

Without defining any designated initializers, classes inherit all initializers of their superclasses.

A pretty easy fix, but a big gotcha that had me stumped for a while.

查看更多
Melony?
5楼-- · 2020-01-28 03:33

My solution is a quick fix, but I think is easier than what Apple purposes on the the Release Notes. For more information search for 19775924 http://adcdownload.apple.com//Developer_Tools/Xcode_6.3_beta_3/Xcode_6.3_beta_3_Release_Notes.pdf here. What Apple says is that you create an Objective-C file and extend it (having to add it to the header files and all) and it's on "Known Issues in Xcode 6.3 beta 3", so I think is easy to do what I did:

This is how I fixed it for UIButton:

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

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

And this is one of my ViewControllers (remove public if not needed):

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")
    }
}

I don't use IB so I also have UIView, because I do separate the view from the viewController (remove public if not needed):

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

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

I need this specially in views because I have a setupViews method that I override in all subclasses that is called on the init. And using AutoLayout I don't need any frames (so I don't override the init with the frame parameter).

So it seems you have to drop override. Oh! and be sure to not call self.init() or the class is never initialized (and it crashes after some internal timeout).

查看更多
Melony?
6楼-- · 2020-01-28 03:33

I think this is way easier than it seems.

For an SKSpriteNode, I was doing this:

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

The problem is init() is not the designated initializer for SKSpriteNode. So I just changed it to:

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

Now it works fine.

查看更多
登录 后发表回答