Класс не имеет инициализаторов Swift


181

У меня проблема с классом Swift. У меня есть быстрый файл для класса UITableViewController и класса UITableViewCell. Моя проблема - это класс UITableViewCell и выходы. Этот класс имеет ошибку. Класс "HomeCell" не имеет инициализаторов , и я не понимаю эту проблему.

Спасибо за ваши ответы.

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

}

Вам нужно явно указать тип переменной nib как необязательный UINib?
Cocoadelica

Ответы:


257

Вы должны использовать неявно развернутые необязательные параметры, чтобы Swift мог справляться с циклическими зависимостями (в этом случае parent <-> child компонентов UI) на этапе инициализации.

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

Прочитайте этот документ , они все это хорошо объяснят.


21
Ваше объяснение и этот документ имеют для меня смысл, но не сообщение об ошибке!
Коко

4
Это, наверное, вопрос к Apple
mprivat

Также @IBOutlets должен быть отмечен как слабый, чтобы избежать сохранения цикла.
Денис Пашков

@ Денис Пашков Насколько я знаю, это только для IBOutlets, который находится в иерархии представления viewController. В противном случае он будет выпущен немедленно, потому что никто его не держит.
Олстон

3
У меня была эта проблема, когда я определил использование Bool var myBool: Bool.
jungledev

96

Быстрое исправление - убедитесь, что все переменные, которые не инициализируются при их создании (например, var num : Int?vs var num = 5), имеют либо a, ?либо !.

Длинный ответ (рекомендуется) - читайте документ в соответствии с предложением mprivat ...


Чтобы устранить эту ошибку, вам нужно установить значение по умолчанию для? переменные, например: пусть showUserPointViewDelegate: ShowUserPointsViewControllerControl? = ноль
Владимир Водолазский

+1 ?означает, что это может быть ноль, но если это так, то нет проблем с движением вперед и бездействием. !означает, что если после распаковки было ноль, то сбой - оба они удовлетворяют требованию инициации - сообщая компилятору: я знаю / хочу, чтобы он начинал с нуля.
Honey

Ищите varи letу вас просматриваете контроллер, и ищите недостающие !s и ?s
Wiingaard

33

Это из Apple Doc

Классы и структуры должны установить для всех своих сохраненных свойств соответствующее начальное значение ко времени создания экземпляра этого класса или структуры. Сохраненные свойства нельзя оставлять в неопределенном состоянии.

Вы получаете сообщение об ошибке. Класс «HomeCell» не имеет инициализаторов, потому что ваши переменные находятся в неопределенном состоянии. Либо вы создаете инициализаторы, либо вы делаете их необязательными типами, используя! или ?


32

Мой ответ касается ошибки в целом, а не точного кода ОП. Ни один ответ не упомянул эту заметку, поэтому я просто подумал, что добавлю ее.

Код ниже также вызовет ту же ошибку:

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
}

Другие упоминали, что либо вы создаете инициализаторы, либо вы делаете их необязательными типами, используя! или ? что правильно. Однако , если у Вас есть дополнительный член / свойства, которые необязательно должны быть изменяемым то есть var. Если вы сделаете это, letон никогда не сможет выйти из своего nilсостояния. Это плохо!

Итак, правильный способ написания:

Опция 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!
}

Или вы можете написать это как:

Option2

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

или по умолчанию это любое значение (в том числе nilи глупое)

Вариант3

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

Если вам интересно, почему let(вопреки var) не инициализируется, nilто читайте здесь и здесь


2
Спасибо за добавление этого, поскольку это была критическая часть картины.
Джим

Хорошо объяснил !!
Махендра

1
Установка на ноль не глупа, но присуща тому, сколько моделей работает.
..

@ drew .. установка чего-то неизменного nil- это очень неправильно. Установка varв nilэто другая вещь.
Мед

Эй, дорогая, кто говорил с неизменными объектами?
..

10

В моем случае я объявил Boolтак:

var isActivityOpen: Bool 

т.е. я объявил это без распаковки так, вот как я решил ( без инициализатора ) ошибку:

var isActivityOpen: Bool!

1

Не конкретный ответ на ваш вопрос, но я получил эту ошибку, когда я не установил начальное значение для перечисления при объявлении его как свойства. Я назначил начальное значение перечислению, чтобы устранить эту ошибку. Размещение здесь, так как это может помочь кому-то.


0

просто предоставьте блок инициализации для класса HomeCell

это работа в моем случае

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.