A classe não tem inicializadores Swift

181

Eu tenho um problema com a classe Swift. Eu tenho um arquivo rápido para a classe UITableViewController e a classe UITableViewCell. Meu problema é a classe UITableViewCell e outlets. Esta classe tem um erro A classe "HomeCell" não possui inicializadores e eu não entendo esse problema.

Obrigado por suas respostas.

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
fonte
Você precisa declarar explicitamente o tipo da variável nib como um UINib opcional?
Cocoadelica

Respostas:

257

Você precisa usar opcionais implicitamente desembrulhados para que o Swift possa lidar com dependências circulares (pai <-> filho dos componentes da interface do usuário nesse caso) durante a fase de inicialização.

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

Leia este documento , eles explicam tudo muito bem.

mprivat
fonte
21
Sua explicação e esse documento fazem sentido para mim, mas não a mensagem de erro!
Coco
4
Isso é provavelmente uma questão para a Apple
mprivat
Também @IBOutlets deve ser marcado como fraco para evitar o ciclo de retenção.
Dennis Pashkov
@Dennis Pashkov Até onde eu sei, é apenas para IBOutlets que está na hierarquia de visualizações do viewController. Caso contrário, ele será liberado imediatamente, porque ninguém o segura.
Alston
3
Eu tive esse problema em que defini um Bool usando var myBool: Bool.
23616 jungledev
96

Solução rápida - verifique se todas as variáveis ​​que não são inicializadas quando são criadas (por exemplo, var num : Int?vs var num = 5) possuem um ?ou !.

Resposta longa (recomendado) - leia o documento conforme sugerido pelo mprivat ...

Byron Coetsee
fonte
Para resolver esse erro, você precisa configurar o valor padrão para? variáveis, por exemplo: deixe showUserPointViewDelegate: ShowUserPointsViewControllerControl? = nil
Vladimir Vodolazkiy
+1 ?significa que pode ser nulo, mas se foi, não há problema em avançar e não fazer nada. !significa que, depois de desembrulhar, ele foi nulo e, em seguida, travar - ambos satisfazem o requisito de iniciação - informando o compilador: eu sei / quero que ele comece do zero.
Querida
Pesquise vare letvisualize o controlador e procure por !s e ?s
ausentes
33

Isto é da Apple doc

Classes e estruturas devem definir todas as suas propriedades armazenadas para um valor inicial apropriado no momento em que uma instância dessa classe ou estrutura é criada. As propriedades armazenadas não podem ser deixadas em um estado indeterminado.

Você recebe a mensagem de erro A classe "HomeCell" não possui inicializadores porque suas variáveis ​​estão em um estado indeterminado. Você cria inicializadores ou os torna opcionais, usando! ou?

CodeHelp
fonte
32

Minha resposta aborda o erro em geral e não o código exato do OP. Nenhuma resposta mencionou esta nota, então pensei em adicioná-la.

O código abaixo também geraria o mesmo erro:

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
}

Outros mencionaram que você cria inicializadores ou os torna opcionais, usando! ou? qual é correto. No entanto, se você tiver um membro / propriedade opcional, esse opcional deverá ser mutável, ou seja var. Se você fizer um let, nunca seria capaz de sair de seu nilestado. Isso é ruim!

Portanto, a maneira correta de escrever é:

Opção 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!
}

Ou você pode escrevê-lo como:

Opção 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!
    }
}

ou use como padrão qualquer valor (incluindo o nilque é meio estúpido)

Opção3

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

Se você está curioso para saber por que let(ao contrário de var) não foi inicializado para niller aqui e aqui

Mel
fonte
2
Obrigado por adicionar isso, pois era uma parte crítica da imagem.
21716 Jim
Bem explicado !!
Mahendra
1
Definir nulo não é estúpido, mas inerente a quantos modelos funcionam.
empate ..
@ drew .. definir algo imutável nilé muito errado. Definir um varpara nilé uma coisa diferente.
Honey
ei querida, quem estava falando com objetos imutáveis?
chamou ..
10

No meu caso, declarei Boolassim:

var isActivityOpen: Bool 

ou seja, eu o declarei sem desembrulhar, é assim que resolvi o erro ( sem inicializador ):

var isActivityOpen: Bool!
Anurag Sharma
fonte
1

Não é uma resposta específica à sua pergunta, mas recebi esse erro quando não havia definido um valor inicial para uma enumeração enquanto a declarava como uma propriedade. Atribuí um valor inicial à enumeração para resolver esse erro. Postando aqui, pois pode ajudar alguém.

Sonu VR
fonte
0

simplesmente forneça o bloco init para a classe HomeCell

é trabalho no meu caso

anoopbryan2
fonte