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

138

У меня проблема с классом 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)
    }

}
  • 0
    Вам нужно явно указать тип переменной nib как необязательный UINib?
Теги:
uitableview

6 ответов

213
Лучший ответ

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

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

Прочитайте это doc, они все это хорошо объясняют.

  • 19
    Ваше объяснение и этот документ имеют для меня смысл, но не сообщение об ошибке!
  • 4
    Это, наверное, вопрос к Apple
Показать ещё 7 комментариев
74

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

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

  • 0
    Чтобы устранить эту ошибку, вам нужно установить значение по умолчанию для? переменные, например: пусть showUserPointViewDelegate: ShowUserPointsViewControllerControl? = ноль
  • 0
    +1 ? означает, что это может быть ноль, но если это так, то нет проблем с движением вперед и бездействием. ! означает, что если после распаковки было ноль, то сбой - оба они удовлетворяют требованию инициации - сообщая компилятору: я знаю / хочу, чтобы он начинал с нуля.
Показать ещё 1 комментарий
28

Это от Apple doc

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

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

10

Простой ответ:

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

В приведенном ниже коде также будет генерироваться ошибка той же:

class Actor {
    let agent : String?
}

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

Таким образом, правильный способ записи:

Option1:

class Actor {
        var agent : String? // it has a chance so its value can be set!
}

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

Option2:

class Actor {
let agent : String?

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

Глубокий ответ:

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

В приведенном ниже коде также будет генерироваться ошибка той же:

class Actor {
    let agent : String? // BAD! // Its value is set to nil, and will always be nil and that 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. Это плохо!

Таким образом, правильный способ записи:

Option1

class Actor {
    var agent : String? // It 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 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
    Спасибо за добавление этого, поскольку это была критическая часть картины.
  • 0
    Хорошо объяснил !!
Показать ещё 1 комментарий
4

В моем случае я объявил Bool следующим образом:

var isActivityOpen: Bool 

то есть. Я объявил это без разворачивания так. Вот как я решил ошибку (без инициализатора):

var isActivityOpen: Bool!
1

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню