Die Klasse 'ViewController' hat keine Initialisierer in Swift


122

Ich bekomme die Beschwerde vom Compiler, wenn ich das mache

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

Wenn ich jedoch nur hinzufüge ? am Ende von AppDelegate wie unten und der Fehler ist weg.

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

Ich sehe kein optionalfür diesen Fehler relevantes Schlüsselwort, es sei denn, ich liege falsch.

Antworten:


238

Der Fehler könnte verbessert werden, aber das Problem mit Ihrer ersten Version ist, dass Sie eine Mitgliedsvariable haben delegate, die keinen Standardwert hat. Alle Variablen in Swift müssen immer einen Wert haben. Das bedeutet, dass Sie es in einem Initialisierer einrichten müssen, den Sie nicht haben, oder Sie könnten ihm einen Standardwert inline geben.

Wenn Sie es optional machen, lassen Sie es nilstandardmäßig zu, sodass Sie es nicht explizit mit einem Wert versehen oder initialisieren müssen.


45

In der Programmiersprache Swift heißt es:

Klassen und Strukturen müssen alle ihre gespeicherten Eigenschaften auf einen geeigneten Anfangswert setzen, wenn eine Instanz dieser Klasse oder Struktur erstellt wird. Gespeicherte Eigenschaften können nicht in einem unbestimmten Zustand belassen werden.

Sie können einen Anfangswert für eine gespeicherte Eigenschaft in einem Initialisierer festlegen oder einen Standardeigenschaftswert als Teil der Definition der Eigenschaft zuweisen.

Daher können Sie schreiben:

class myClass {

    var delegate: AppDelegate //non-optional variable

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

}

Oder:

class myClass {

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

    init() {
        println("Hello")
    }

}

Oder:

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
    }

}

Aber Sie können nicht folgendes schreiben:

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

Manchmal tritt dieser Fehler auch auf, wenn Sie eine Var oder eine Let haben, die nicht initialisiert wurde.

Beispielsweise

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

Abhängig davon, was Ihre Variable tun soll, können Sie diesen Variablentyp entweder als optional festlegen oder mit einem Wert wie dem folgenden initialisieren

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
}

Was ist die Lösung dafür?
Martian2049

Können sie stattdessen in einer Init-Funktion aktiviert werden?
Martian2049

12

Dieses Problem tritt normalerweise auf, wenn eine Ihrer Variablen keinen Wert hat oder wenn Sie vergessen, "!" um diese Variable zu zwingen, nil zu speichern, bis sie gesetzt ist.

In Ihrem Fall ist das Problem hier:

var delegate: AppDelegate

Es sollte so definiert werden var delegate: AppDelegate!, dass es eine Option ist, die Null speichert und die Variable erst auspackt, wenn der Wert verwendet wird.

Es ist traurig, dass Xcode die gesamte Klasse als Fehler hervorhebt, anstatt die bestimmte Codezeile hervorzuheben, die sie verursacht hat. Daher dauert es eine Weile, bis sie herausgefunden ist.


Dadurch wird die Fehlermeldung für mich bei einem IBOutlet beseitigt, bei Standardvariablen jedoch nicht.
Tim Vermeulen

Dies löst mein Problem. Als ich dies versuchte: var fetchedResultsController: NSFetchedResultsController Ich habe den Kompilierungsfehler erhalten. Beim Hinzufügen "!" Der Fehler ging weg, wie so var fetchedResultsController: NSFetchedResultsController!
Jervisbay

danke für ur ans! Das ist hilfreich für mich, ich habe gerade "?" auf optionalen Wert aber "!" Ich habe es vorher nicht gewusst. Ich setze "!" so: var time: NSTimer!
AmyNguyen

10

wenn du ein "!" In Ihrem Code, wie in diesem Code unten, wird auch dieser Fehler angezeigt.

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

Ersetzen Sie var appDelegate : AppDelegate?durch let appDelegate = UIApplication.sharedApplication().delegatewie in der zweiten kommentierten Zeile in angegeben viewDidLoad().

Das Schlüsselwort "optional" bezieht sich genau auf die Verwendung von ?, siehe dies für weitere Details.


1

Ich benutze Xcode 7 und Swift 2. Zuletzt hatte ich gemacht:

Klasse ViewController: UIViewController {var time: NSTimer // Fehler hier}

Dann behebe ich: Klasse 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)
}

}}


Die Klarheit ist nicht ganz alles in Ihrer Antwort, aber das war mein Problem; Ich habe die Optionalität eines Mitglieds var nicht angegeben (erzwungen / optional). Nachdem ich dies getan und den Code später angepasst hatte, beschwerte sich ViewController nicht mehr darüber, keinen Initialisierer zu haben.
James Perih

0

Für mich war eine Erklärung unvollständig. Beispielsweise:

var isInverted: Bool

Stattdessen der richtige Weg:

var isInverted: Bool = false
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.