La classe 'ViewController' n'a pas d'initialiseur dans swift


123

Obtenir la plainte du compilateur lorsque je fais cela

class ViewController: UIViewController {

    var delegate : AppDelegate
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //self.appDelegate = UIApplication.sharedApplication().delegate;

    }

    @IBAction func getData(sender : AnyObject) {

    }

    @IBAction func LogOut(sender : AnyObject) {
    }
}

Cependant, si je viens d'ajouter ? à la fin d' AppDelegate comme ci-dessous et l'erreur a disparu.

class ViewController: UIViewController {

    var delegate : AppDelegate?
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //self.appDelegate = UIApplication.sharedApplication().delegate;

    }

    @IBAction func getData(sender : AnyObject) {

    }

    @IBAction func LogOut(sender : AnyObject) {
    }
}

Je ne vois pas de optionalmot clé pertinent pour cette erreur, sauf si je me trompe.

Réponses:


240

L'erreur pourrait être améliorée, mais le problème avec votre première version est que vous avez une variable membre,, delegatequi n'a pas de valeur par défaut. Toutes les variables de Swift doivent toujours avoir une valeur. Cela signifie que vous devez le configurer dans un initialiseur que vous n'avez pas ou vous pouvez lui fournir une valeur par défaut en ligne.

Lorsque vous le rendez facultatif, vous l'autorisez nilpar défaut, en supprimant la nécessité de lui donner explicitement une valeur ou de l'initialiser.


45

Le langage de programmation Swift déclare:

Les classes et les structures doivent définir toutes leurs propriétés stockées sur une valeur initiale appropriée au moment où une instance de cette classe ou structure est créée. Les propriétés stockées ne peuvent pas être laissées dans un état indéterminé.

Vous pouvez définir une valeur initiale pour une propriété stockée dans un initialiseur ou en attribuant une valeur de propriété par défaut dans le cadre de la définition de la propriété.

Par conséquent, vous pouvez écrire:

class myClass {

    var delegate: AppDelegate //non-optional variable

    init() {
        delegate = UIApplication.sharedApplication().delegate as AppDelegate
    }

}

Ou:

class myClass {

    var delegate = UIApplication.sharedApplication().delegate as AppDelegate //non-optional variable

    init() {
        println("Hello")
    }

}

Ou:

class myClass {

    var delegate : AppDelegate! //implicitly unwrapped optional variable set to nil when class is initialized

    init() {
        println("Hello")
    }

    func myMethod() {
        delegate = UIApplication.sharedApplication().delegate as AppDelegate
    }

}

Mais vous ne pouvez pas écrire ce qui suit:

class myClass {

    var delegate : AppDelegate //non-optional variable

    init() {
        println("Hello")
    }

    func myMethod() {
        //too late to assign delegate as an non-optional variable
        delegate = UIApplication.sharedApplication().delegate as AppDelegate
    }

}

22

Parfois, cette erreur apparaît également lorsque vous avez un var ou un let qui n'a pas été initialisé.

Par exemple

class ViewController: UIViewController {
    var x: Double
    // or
    var y: String
    // or
    let z: Int
}

En fonction de ce que votre variable est censée faire, vous pouvez soit définir ce type de var comme facultatif, soit l'initialiser avec une valeur comme celle-ci

class ViewController: UIViewCOntroller {
    // Set an initial value for the variable
    var x: Double = 0
    // or an optional String
    var y: String?
    // or
    let z: Int = 2
}

alors quelle est la solution à cela?
Martian2049

peuvent-ils être introduits dans une fonction init à la place?
Martian2049

13

Ce problème apparaît généralement lorsque l'une de vos variables n'a aucune valeur ou lorsque vous oubliez d'ajouter "!" pour forcer cette variable à stocker nil jusqu'à ce qu'elle soit définie.

Dans votre cas, le problème est ici:

var delegate: AppDelegate

Il doit être défini de manière var delegate: AppDelegate!à en faire un optionnel qui stocke nil et ne déroule pas la variable tant que la valeur n'est pas utilisée.

Il est triste que Xcode met en évidence toute la classe comme une erreur au lieu de mettre en évidence la ligne de code particulière qui l'a provoquée, il faut donc un certain temps pour la comprendre.


Cela supprime le message d'erreur pour moi dans le cas d'un IBOutlet, mais pas dans le cas d'une variable standard.
Tim Vermeulen

Cela résout mon problème. Quand j'ai essayé de faire ceci: var fetchedResultsController: NSFetchedResultsController j'ai eu l'erreur de compilation. En ajoutant "!" l'erreur a disparu, comme var fetchedResultsController: NSFetchedResultsController!
Jervisbay

merci pour vos ans! C'est utile pour moi, je viens de savoir "?" à une valeur facultative mais "!" Je ne l'ai pas su avant. J'ai mis "!" comme ça: var time: NSTimer!
AmyNguyen

10

si vous avez perdu un "!" dans votre code, comme ce code ci-dessous, vous obtiendrez également cette erreur.

import UIKit

class MemeDetailViewController : UIViewController {

    @IBOutlet weak var memeImage: UIImageView!

    var meme:Meme! // lost"!"

    override func viewWillAppear(animated: Bool) {

        super.viewWillAppear(animated)
        self.memeImage!.image = meme.memedImage
    }

    override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
    }

}

3

Remplacez var appDelegate : AppDelegate?par let appDelegate = UIApplication.sharedApplication().delegatecomme indiqué sur la deuxième ligne commentée dans viewDidLoad().

Le mot-clé "facultatif" se réfère exactement à l'utilisation de ?, voir ceci pour plus de détails.


1

J'utilise Xcode 7 et Swift 2. Enfin, j'avais fait:

class ViewController: UIViewController {var time: NSTimer // erreur ceci ici}

Ensuite, je corrige: class ViewController: UIViewController {

var time: NSTimer!
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func viewWillAppear(animated: Bool) {
    //self.movetoHome()
    time = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: #selector(ViewController.movetoHome), userInfo: nil, repeats: false)
    //performSegueWithIdentifier("MoveToHome", sender: self)
    //presentViewController(<#T##viewControllerToPresent: UIViewController##UIViewController#>, animated: <#T##Bool#>, completion: <#T##(() -> Void)?##(() -> Void)?##() -> Void#>)
}

func movetoHome(){
    performSegueWithIdentifier("MoveToHome", sender: self)
}

}


La clarté n'est pas tout à fait là dans votre réponse, mais c'était mon problème; Je n'ai pas spécifié le caractère facultatif d'un membre var (forcé / facultatif); une fois que je l'ai fait, et ajusté le code plus tard, ViewController ne s'est plus plaint de ne pas avoir d'initialiseur.
James Perih

0

Pour moi, c'était une déclaration incomplète. Par exemple:

var isInverted: Bool

Au lieu de cela la bonne manière:

var isInverted: Bool = false
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.