La clase no tiene inicializadores Swift

181

Tengo un problema con la clase Swift. Tengo un archivo rápido para la clase UITableViewController y la clase UITableViewCell. Mi problema es la clase UITableViewCell y los puntos de venta. Esta clase tiene un error La clase "HomeCell" no tiene inicializadores , y no entiendo este problema.

Gracias por sus respuestas

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

}
Kevin Py
fuente
¿Necesita indicar explícitamente el tipo de la variable nib como un UINib opcional?
Cocoadelica

Respuestas:

257

Debe usar opciones implícitamente desenvueltas para que Swift pueda hacer frente a las dependencias circulares (padre <-> hijo de los componentes de la IU en este caso) durante la fase de inicialización.

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

Lea este documento , lo explican todo muy bien.

mprivat
fuente
21
Su explicación y ese documento tienen sentido para mí, ¡pero no el mensaje de error!
coco
44
Esa es probablemente una pregunta para Apple
mprivat
También @IBOutlets debe marcarse como débil para evitar el ciclo de retención.
Dennis Pashkov
@Dennis Pashkov Hasta donde yo sé, es solo para IBOutlets que está en la vista Jerarquía de vista del controlador. De lo contrario, se liberará de inmediato porque nadie lo tiene.
Alston
3
Tuve este problema donde definí un Bool usando var myBool: Bool.
jungledev
96

Solución rápida: asegúrese de que todas las variables que no se inicializan cuando se crean (p. Ej., var num : Int?Vs var num = 5) tengan una ?o una !.

Respuesta larga (recomendada): lea el documento según sugiere mprivat ...

Byron Coetsee
fuente
Para resolver este error, debe configurar el valor predeterminado para? variables, por ejemplo: let showUserPointViewDelegate: ShowUserPointsViewControllerControl? = nulo
Vladimir Vodolazkiy
+1 ?significa que puede ser nulo, pero si lo fuera, entonces no hay problema para seguir adelante y no hacer nada. !significa que si después de desenvolver fue nulo, se bloquea (ambos satisfacen el requisito de iniciación) informando al compilador: Sé / quiero que comience de cero.
Miel
Buscar vary leten el controlador de ver y buscar a una !s y ?s
Wiingaard
33

Esto es de Apple doc

Las clases y estructuras deben establecer todas sus propiedades almacenadas en un valor inicial apropiado para el momento en que se crea una instancia de esa clase o estructura. Las propiedades almacenadas no se pueden dejar en un estado indeterminado.

Recibe el mensaje de error La clase "HomeCell" no tiene inicializadores porque sus variables están en un estado indeterminado. O creas inicializadores o los haces tipos opcionales, usando! o

CodeHelp
fuente
32

Mi respuesta aborda el error en general y no el código exacto del OP. Ninguna respuesta mencionó esta nota, así que pensé en agregarla.

El siguiente código también generaría el mismo error:

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
}

¡Otros mencionaron que creas inicializadores o los haces tipos opcionales, usando! o cual es correcta. Sin embargo, si tiene un miembro / propiedad opcional, ese opcional debería ser mutable, es decir var. Si haces un, letentonces nunca podría salir de su nilestado. ¡Eso es malo!

Entonces, la forma correcta de escribirlo es:

Opción 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!
}

O puedes escribirlo como:

Opcion 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!
    }
}

o por defecto a cualquier valor (incluido el nilque es un poco estúpido)

Opcion3

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

Si tiene curiosidad sobre por qué let(al contrario de var) no está inicializado nil, lea aquí y aquí

Miel
fuente
2
Gracias por agregar esto, ya que era una parte crítica de la imagen.
Jim
¡¡Bien explicado!!
Mahendra
1
Establecer en cero no es estúpido, sino inherente a la cantidad de modelos que funcionan.
sorteo ..
@drew ... establecer algo inmutable niles muy incorrecto. Establecer un vara niles una cosa diferente.
Miel
Hola cariño, ¿quién estaba hablando con objetos inmutables?
sorteo ..
10

En mi caso, he declarado algo Boolasí:

var isActivityOpen: Bool 

es decir, lo declare sin desenvolver, así es como resolví el error ( sin inicializador ):

var isActivityOpen: Bool!
Anurag Sharma
fuente
1

No es una respuesta específica a su pregunta, pero recibí este error cuando no había establecido un valor inicial para una enumeración al declararlo como una propiedad. Asigne un valor inicial a la enumeración para resolver este error. Publicar aquí ya que podría ayudar a alguien.

Sonu VR
fuente
0

simplemente proporcione el bloque de inicio para la clase HomeCell

es trabajo en mi caso

anoopbryan2
fuente