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.

tranvutuan
quelle

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.

Drawag
quelle
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
    }

}
Imanou Petit
quelle
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
}
Oliver S.
quelle
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.

Ivan V.
quelle
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)
    }

}
saneryee
quelle
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.

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

}}

AmyNguyen
quelle
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
Alessandro Mattiuzzi
quelle