La classe "ViewController" non ha inizializzatori in swift


123

Ottenere il reclamo dal compilatore quando lo faccio

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

Tuttavia, se aggiungo solo ? alla fine di AppDelegate come sotto e l'errore è sparito.

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

Non vedo la optionalparola chiave pertinente a questo errore a meno che non sbaglio.

Risposte:


240

L'errore potrebbe essere migliorato, ma il problema con la tua prima versione è che hai una variabile membro,, delegateche non ha un valore predefinito. Tutte le variabili in Swift devono sempre avere un valore. Ciò significa che devi configurarlo in un inizializzatore che non hai o potresti fornirgli un valore predefinito in linea.

Quando lo rendi facoltativo, lo consenti per nilimpostazione predefinita, eliminando la necessità di assegnargli esplicitamente un valore o inizializzarlo.


45

Lo Swift Programming Language afferma:

Le classi e le strutture devono impostare tutte le loro proprietà memorizzate su un valore iniziale appropriato prima che venga creata un'istanza di quella classe o struttura. Le proprietà memorizzate non possono essere lasciate in uno stato indeterminato.

È possibile impostare un valore iniziale per una proprietà memorizzata all'interno di un inizializzatore o assegnando un valore di proprietà predefinito come parte della definizione della proprietà.

Pertanto, puoi scrivere:

class myClass {

    var delegate: AppDelegate //non-optional variable

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

}

O:

class myClass {

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

    init() {
        println("Hello")
    }

}

O:

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
    }

}

Ma non puoi scrivere quanto segue:

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

A volte questo errore appare anche quando hai una var o una let che non è stata inizializzata.

Per esempio

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

A seconda di ciò che la tua variabile dovrebbe fare, potresti impostare quel tipo di var come opzionale o inizializzarlo con un valore come il seguente

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
}

quindi qual è la soluzione a questo?
Martian 2049

possono essere invece avviati in una funzione init?
Martian 2049

13

Questo problema di solito si verifica quando una delle tue variabili non ha alcun valore o quando ti dimentichi di aggiungere "!" per forzare questa variabile a memorizzare nil finché non viene impostata.

Nel tuo caso il problema è qui:

var delegate: AppDelegate

Dovrebbe essere definito in modo var delegate: AppDelegate!da renderlo un opzionale che memorizza nil e non scartare la variabile finché non viene utilizzato il valore.

È triste che Xcode evidenzi l'intera classe come un errore invece di evidenziare la particolare riga di codice che l'ha causata, quindi ci vuole un po 'per capirlo.


Questo mi elimina il messaggio di errore nel caso di un IBOutlet, ma non nel caso di variabili standard.
Tim Vermeulen

Questo risolve il mio problema. Quando ho provato a farlo: var fetchedResultsController: NSFetchedResultsController ho ricevuto l'errore di compilazione. Aggiungendo "!" l'errore è andato via, in questo modo var fetchedResultsController: NSFetchedResultsController!
Jervisbay

grazie per ur ans! Questo è utile per me, ho appena saputo "?" al valore opzionale ma "!" Non lo sapevo prima. Ho impostato "!" in questo modo: var time: NSTimer!
AmyNguyen

10

se hai perso un "!" nel tuo codice, come questo codice qui sotto, riceverai anche questo errore.

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

Sostituisci var appDelegate : AppDelegate?con let appDelegate = UIApplication.sharedApplication().delegatecome suggerito nella seconda riga commentata in viewDidLoad().

La parola chiave "opzionale" si riferisce esattamente all'uso di ?, vedere questo per maggiori dettagli.


1

Uso Xcode 7 e Swift 2. Infine, avevo fatto:

class ViewController: UIViewController {var time: NSTimer // error this here}

Quindi aggiusto: 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 chiarezza non è del tutto presente nella tua risposta, ma questo era il mio problema; Non ho specificato l'opzionalità di un membro var (forzato / opzionale); una volta fatto, e modificato il codice in seguito, ViewController non si è più lamentato di non avere un inizializzatore.
James Perih

0

Per me è stata una dichiarazione incompleta. Per esempio:

var isInverted: Bool

Invece nel modo corretto:

var isInverted: Bool = false
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.