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

}

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.


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 ...


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?


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


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!

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.


0

simplesmente forneça o bloco init para a classe HomeCell

é trabalho no meu caso

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.