Клас не має ініціалізаторів 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 міг впоратися з циркулярними залежностями (батьківський <-> дочірніх компонентів інтерфейсу в цьому випадку) під час фази ініціалізації.

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

Прочитайте цього документа , вони все гарно пояснюють.


21
Твоє пояснення та цей документ, для мене все має сенс, але не повідомлення про помилку!
coco

4
Це, мабуть, питання для Apple
mprivat

Також @IBOutlets слід позначати як слабкий, щоб уникнути збереження циклу.
Денніс Пашков

@Dennis Pashkov Наскільки я знаю, це є лише для IBOutlets, що перебуває в ієрархії подання viewController. В іншому випадку він буде звільнений негайно, оскільки його ніхто не тримає.
Альстон

3
У мене була ця проблема, коли я визначав використання Bool var myBool: Bool.
jungledev

96

Швидке виправлення - переконайтеся , що всі змінні , що не започатковано при їх створенні (наприклад , var num : Int?проти var num = 5) мають або ?або !.

Довга відповідь (рекомендовано) - прочитайте документ, як пропонує mprivat ...


Для усунення цієї помилки вам потрібно встановити значення за замовчуванням? змінні, наприклад: нехай showUserPointViewDelegate: ShowUserPointsViewControllerControl? = нуль
Володимир Водолазький

+1 ?означає, що це може бути нульовим, але якщо це було, то немає проблеми з рухом вперед і нічого не робити. !означає, що якщо після розгортання він був нульовим, то аварія - обидва вони задовольняють вимогу ініціації - повідомляючи компілятора: я знаю / хочу, що він почне форму нуля.
Мед

Шукайте varі letви переглядаєте контролер, і шукайте відсутні !і ?з
Wiingaard

33

Це від доктора Apple

Класи та структури повинні встановлювати всі їх збережені властивості до відповідного початкового значення до моменту створення екземпляра цього класу чи структури. Збережені властивості не можна залишити у невизначеному стані.

Ви отримуєте повідомлення про помилку Клас "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!
}

Або ви можете написати це як:

Варіант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!
    }
}

або за замовчуванням до будь-якого значення (включаючи якесь nilдурне)

Варіант3

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

Якщо вам цікаво, чому let(всупереч var) не ініціалізовано nilчитати тут і тут


2
Дякую, що додали це, оскільки це було важливою частиною картини.
Джим

Добре пояснено !!
Махендра

1
Постановка на нуль не дурна, але притаманна тому, скільки моделей працює.
малював ..

@drew .. налаштовувати щось незмінне nil, дуже помилково. Установка varTo nilце інша справа.
Мед

ей, дорогий, хто розмовляв із незмінними предметами?
малював ..

10

У моєму випадку я заявив Boolтак:

var isActivityOpen: Bool 

тобто я оголосив це, не розгортаючи, так, ось як я вирішив помилку ( без ініціалізатора ):

var isActivityOpen: Bool!

1

Не конкретна відповідь на ваше запитання, але я отримав цю помилку, коли я не встановив початкове значення для enum, оголошуючи його як властивість. Енум я призначив початкове значення, щоб вирішити цю помилку. Опублікувати тут, як це може комусь допомогти.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.