【问题标题】:Class has no initializers Swift类没有初始化器 Swift
【发布时间】:2015-03-04 01:01:38
【问题描述】:

我对 Swift 课程有疑问。我有一个用于 UITableViewController 类和 UITableViewCell 类的 swift 文件。我的问题是 UITableViewCell 类和网点。这个类有一个错误Class "HomeCell" has no initializers,我不明白这个问题。

感谢您的回复。

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?

标签: ios uitableview swift


【解决方案1】:

您必须使用隐式展开的可选选项,以便 Swift 可以在初始化阶段处理循环依赖(在这种情况下是 UI 组件的父 子组件)。

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

阅读此doc,他们很好地解释了这一切。

【讨论】:

  • 你的解释,还有那个文档,对我来说都是有意义的,但错误信息却没有!
  • 这可能是苹果的问题
  • 还应将@IBOutlets 标记为弱,以避免保留循环。
  • @Dennis Pashkov 据我所知,它仅适用于 viewController 的视图层次结构中的 IBOutlets。否则它会立即释放,因为没有人持有它。
  • 我遇到了这个问题,我使用var myBool: Bool 定义了一个布尔值。
【解决方案2】:

快速修复 - 确保所有在创建时未初始化的变量(例如 var num : Int?var num = 5)具有 ?!

长答案(推荐) - 按照 mprivat 的建议阅读 doc...

【讨论】:

  • 要解决此错误,您需要设置默认值?变量,例如: let showUserPointViewDelegate : ShowUserPointsViewControllerControl? = 无
  • +1 ? 表示它可能为零,但如果是,那么继续前进并且什么都不做是没有问题的。 ! 表示如果在解包后它是 nil,然后崩溃——这两个满足启动要求——通过你通知编译器:我知道/希望它会从 nil 开始。
  • 在你的视图控制器中搜索varlet,并寻找缺少的!s和?s
【解决方案3】:

这是来自 Apple doc

在创建该类或结构的实例时,类和结构必须将其所有存储的属性设置为适当的初始值。存储的属性不能处于不确定状态。

您收到错误消息Class "HomeCell" has no initializers,因为您的变量处于不确定状态。要么创建初始化器,要么将它们设为可选类型,使用 !还是?

【讨论】:

    【解决方案4】:

    我的回答通常解决了错误,而不是 OP 的确切代码。没有答案提到这个注释,所以我只是想我添加它。

    下面的代码也会产生same错误:

    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,那么请阅读herehere

    【讨论】:

    • 感谢您添加此内容,因为它是图片的关键部分。
    • 解释得好!!
    • 设置为零并不愚蠢,而是有多少模型可以工作。
    • @drew.. 将不可变的东西设置为 nil 是非常错误的。将var 设置为nil 是另一回事。
    • 嘿亲爱的,谁在和不可变对象说话?
    【解决方案5】:

    在我的例子中,我已经声明了一个 Bool 像这样:

    var isActivityOpen: Bool 
    

    即我没有展开就声明了它,这就是我解决 (no initializer) 错误的方法:

    var isActivityOpen: Bool!
    

    【讨论】:

      【解决方案6】:

      不是您问题的具体答案,但是当我在将枚举声明为属性时没有为枚举设置初始值时出现此错误。我为枚举分配了一个初始值来解决这个错误。 在这里发帖可能会对某人有所帮助。

      【讨论】:

        【解决方案7】:

        只需为 HomeCell 类提供初始化块

        对我来说是有效的

        【讨论】: