web-dev-qa-db-fra.com

L'initialiseur ne remplace pas un initialiseur désigné de sa super-classe

Donc, je viens de passer à Xcode 6.3 Bêta 3 et beaucoup d’erreurs apparaissent concernant les éléments suivants:

L'initialiseur ne remplace pas un initialiseur désigné de sa super-classe.

override init() {
    super.init()
}

Par exemple, il s'agit d'une classe UIButton:

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

C'est l'une de mes 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)
    }
}
37
fuzz

Ma solution est une solution rapide, mais je pense que c'est plus facile que ce que Apple utilise dans les notes de version. Pour plus d'informations, recherchez 19775924 http://adcdownload.Apple.com //Developer_Tools/Xcode_6.3_beta_3/Xcode_6.3_beta_3_Release_Notes.pdf Ce que Apple indique que vous créez un fichier Objective-C et que vous l'étendez (en l'ajoutant à l'en-tête) fichiers et tous) et il est sur "Problèmes connus dans Xcode 6.3 beta 3", donc je pense qu'il est facile de faire ce que j'ai fait:

Voici comment je l'ai corrigé pour UIButton:

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

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

Et ceci est l'un de mes ViewControllers (retirer public sinon nécessaire):

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

Comme je n'utilise pas IB, j'ai aussi UIView, car je sépare la vue de la viewController (supprime public si non nécessaire):

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

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

J'ai besoin de cela spécialement dans les vues car j'ai une méthode setupViews que je remplace dans toutes les sous-classes qui sont appelées à l'init. Et en utilisant AutoLayout, je n'ai besoin d'aucun cadre (donc je ne remplace pas l'init par le paramètre frame).

Il semble donc que vous deviez abandonner override. Oh! et assurez-vous de ne pas appeler self.init(), sinon la classe n'est jamais initialisée (et se bloque après un certain délai interne).

43
Lluis Gerard

Selon Apple documentation ici , ce que vous substituez est un initialiseur simple. Ainsi, pour que votre initialiseur fonctionne, vous devrez changer la méthode en

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

Vous pouvez le faire ou supprimer l'initialiseur si vous ne l'utilisez pas réellement, à l'exception de l'appel de l'initialiseur de superclasse.

4
lostInTransit

Je pense que c'est beaucoup plus facile qu'il n'y parait.

Pour un SKSpriteNode, je faisais ceci:

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

Le problème est init () n'est pas l'initialiseur désigné pour SKSpriteNode. Alors je viens de le changer en:

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

Maintenant cela fonctionne bien.

3
user3590685

Solution for Error: Le remplacement de init (codeur aDecoder: NSCoder!) Ne fonctionne pas comme prévu - Swift

Cela fonctionne pour moi, essayez ceci, Remarque: vous devez vous réveiller

override func awakeFromNib() {

     super.awakeFromNib()
    // Initialisation code

}
1
Sanju

J'ai récemment compris cela et j'aimerais expliquer quel était le problème. Répondu à l'origine sur le forums de développeurs Apple .

Il semble que Swift a modifié la stratégie de vérification des dépendances d’initialisation ou d’importation d’initialiseurs.

Maintenant, si vos initialiseurs sont conformes à l’illustration, une façon de traiter à la fois Xcode 6.3 Beta 2 et Beta 3 consiste à supprimer toutes les définitions d’initialiseur:

class CustomButton: UIButton {

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

class CustomAlertView: UIViewController {

}

Sans définir d'initialisateurs désignés, les classes héritent de tous les initialiseurs de leurs super-classes.

Une solution assez facile, mais un gros piège qui m'a laissé perplexe pendant un moment.

1
fuzz