Klasse hat keine Initialisierer Swift


180

Ich habe ein Problem mit der Swift-Klasse. Ich habe eine schnelle Datei für die UITableViewController-Klasse und die UITableViewCell-Klasse. Mein Problem ist die UITableViewCell-Klasse und Outlets. Diese Klasse hat einen Fehler. Klasse "HomeCell" hat keine Initialisierer , und ich verstehe dieses Problem nicht.

Vielen Dank für Ihre Antworten.

import Foundation
import UIKit

class HomeTable: UITableViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet var tableViex: UITableView!

    var items: [(String, String, String)] = [
        ("Test", "123", "1.jpeg"),
        ("Test2", "236", "2.jpeg"),
        ("Test3", "678", "3.jpeg")
    ]

    override func viewDidLoad() {
        super.viewDidLoad()

        var nib = UINib(nibName: "HomeCell", bundle: nil)
        tableView.registerNib(nib, forCellReuseIdentifier: "bookCell")
    }

    // Number row
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.items.count
    }

    // Style Cell
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("bookCell") as UITableViewCell

        // Style here

        return cell

    }

    // Select row
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        // Select
    }

}

// PROBLEM HERE
class HomeCell : UITableViewCell {

    @IBOutlet var imgBook: UIImageView
    @IBOutlet var titleBook: UILabel
    @IBOutlet var pageBook: UILabel

    func loadItem(#title: String, page: String, image:String) {
        titleBook.text = title
        pageBook.text = page
        imgBook.image = UIImage(named: image)
    }

}

Müssen Sie den Typ der nib-Variablen explizit als optionale UINib angeben?
Cocoadelica

Antworten:


257

Sie müssen implizit entpackte Optionen verwenden, damit Swift während der Initialisierungsphase zirkuläre Abhängigkeiten (in diesem Fall übergeordnetes <-> untergeordnetes Element der UI-Komponenten) bewältigen kann.

@IBOutlet var imgBook: UIImageView!
@IBOutlet var titleBook: UILabel!
@IBOutlet var pageBook: UILabel!

Lesen Sie dieses Dokument , sie erklären alles gut.


21
Ihre Erklärung und dieses Dokument machen für mich alle Sinn, aber nicht die Fehlermeldung!
Coco

4
Das ist wahrscheinlich eine Frage für Apple
mprivat

Außerdem sollten @IBOutlets als schwach markiert werden, um einen Beibehaltungszyklus zu vermeiden.
Dennis Pashkov

@ Tennis Pashkov Soweit ich weiß, befindet sich nur für IBOutlets die Ansichtshierarchie von viewController. Andernfalls wird es sofort freigegeben, da niemand es hält.
Alston

3
Ich hatte dieses Problem, bei dem ich einen Bool mit definiert habe var myBool: Bool.
Jungledev

96

Schnellkorrektur - Stellen Sie sicher, dass alle Variablen, die beim Erstellen nicht initialisiert werden (z. B. var num : Int?vs var num = 5), entweder ein ?oder haben !.

Lange Antwort (empfohlen) - Lesen Sie das Dokument gemäß den Vorschlägen von mprivat ...


Um diesen Fehler zu beheben, müssen Sie den Standardwert für? Variablen, zum Beispiel: let showUserPointViewDelegate: ShowUserPointsViewControllerControl? = Null
Vladimir Vodolazkiy

+1 ?bedeutet, dass es vielleicht Null ist, aber wenn es so wäre, gibt es kein Problem damit, vorwärts zu gehen und nichts zu tun. !bedeutet, wenn es nach dem Auspacken Null war, dann Absturz - beide erfüllen die Initiierungsanforderung -, indem Sie den Compiler informieren: Ich weiß / möchte, dass es von Null startet.
Honey

Suchen Sie nach varund letin !?
Ihrem

33

Dies ist aus Apple Doc

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 erhalten die Fehlermeldung Klasse "HomeCell" hat keine Initialisierer, da sich Ihre Variablen in einem unbestimmten Zustand befinden. Entweder erstellen Sie Initialisierer oder Sie machen sie zu optionalen Typen, indem Sie! oder ?


32

Meine Antwort befasst sich mit dem Fehler im Allgemeinen und nicht mit dem genauen Code des OP. Keine Antwort erwähnte diesen Hinweis, also dachte ich nur, ich füge ihn hinzu.

Der folgende Code würde ebenfalls den gleichen Fehler erzeugen :

class Actor {
    let agent : String? // BAD! // Its value is set to nil, and will always be nil and that's stupid so Xcode is saying not-accepted.  
    // Technically speaking you have a way around it🤓, you can help the compiler and enforce your value as a constant. See Option3
}

Andere erwähnten, dass Sie entweder Initialisierer erstellen oder sie mit! oder ? welches ist richtig. Wenn Sie jedoch ein optionales Mitglied / eine optionale Eigenschaft haben, sollte diese optional veränderbar sein, d var. H. Wenn Sie ein letdann machen, würde es nie in der Lage sein, aus seinem nilZustand herauszukommen . Das ist schlecht!

Die richtige Schreibweise lautet also:

Option 1

class Actor {
    var agent : String? // It's defaulted to `nil`, but also has a chance so it later can be set to something different || GOOD!
}

Oder Sie können es schreiben als:

Option 2

class Actor {
let agent : String? // It's value isn't set to nil, but has an initializer || GOOD!

init (agent: String?){
    self.agent = agent // it has a chance so its value can be set!
    }
}

oder standardmäßig einen beliebigen Wert (einschließlich dessen, nilwas irgendwie dumm ist)

Option3

class Actor {
let agent : String? = nil // very useless, but doable.
let company: String? = "Universal" 
}

Wenn Sie neugierig sind, warum let(im Gegensatz zu var) nicht initialisiert wurde, nillesen Sie hier und hier


2
Vielen Dank, dass Sie dies hinzugefügt haben, da es ein kritischer Teil des Bildes war.
Jim

Gut erklärt !!
Mahendra

1
Die Einstellung auf Null ist nicht dumm, hängt jedoch davon ab, wie viele Modelle funktionieren.
zeichnete ..

@ zog .. etwas unveränderlich zu setzen nilist sehr falsch. Ein varzu setzen nilist eine andere Sache.
Honig

Hey Schatz, wer hat mit unveränderlichen Objekten gesprochen?
zeichnete ..

10

In meinem Fall habe ich Folgendes erklärt Bool:

var isActivityOpen: Bool 

dh ich habe es deklariert, ohne es auszupacken. So habe ich den Fehler ( kein Initialisierer ) gelöst :

var isActivityOpen: Bool!

1

Keine spezifische Antwort auf Ihre Frage, aber ich hatte diesen Fehler erhalten, als ich keinen Anfangswert für eine Aufzählung festgelegt hatte, während ich sie als Eigenschaft deklarierte. Ich habe der Aufzählung einen Anfangswert zugewiesen, um diesen Fehler zu beheben. Hier posten, da es jemandem helfen könnte.


0

Geben Sie einfach den Init-Block für die HomeCell- Klasse an

In meinem Fall ist es Arbeit

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.