【问题标题】:IBOutlets and IBactions require ! in the endIBOutlets 和 IBactions 需要!到底
【发布时间】:2015-02-16 23:16:12
【问题描述】:

我今天尝试从 Obj-C 开始并转到 Swift,我正在阅读文档。我尝试在 Swift 中创建一个简单的 IBOutlet,但它不断给我这些错误。

View Controller has no initialiser

必需的初始化(编码器aDecoder:NSCoder){ fatalError("init(coder:) 尚未实现") }

IBOutletproperty has non-optional type 'UILabel'

并且不断弹出以下代码:

@IBOutlet var outputLabel : UILabel

但是当我添加一个 !标记,它运行没有像这样的错误

@IBOutlet var outputLabel : UILabel!

同样的事情发生在 IBActions...

【问题讨论】:

  • 我建议阅读第二个答案:stackoverflow.com/questions/24006975/… 非常有用。
  • @DánielNagy 我可能会问,我在网上查看了一些视频教程,但他们从来没有放过!...为什么他们和我们必须这样做?谢谢
  • 视频教程可能已经过时 - 最初 IBOutlet 装饰器也将属性设为可选,这很早就被更改了。
  • 是的,正如@jrturton 所说。现在你必须把!在 and,因为它只有在初始化之后才会有它的值。
  • 好的。非常感谢大家!!

标签: ios swift xcode6 iboutlet


【解决方案1】:

首先了解一下!?究竟是什么

  • 使用? :如果该值将来可以变为nil,以便您对此进行测试。
  • 使用! :如果它真的不应该在未来变为 nil,但最初需要为 nil。

@IBOutlet:

当你在 Swift 中声明一个 outlet 时,编译器会自动将类型转换为 weak 隐式展开可选,并为其分配一个初始值nil

实际上,编译器将@IBOutlet var name: 类型替换为@IBOutlet weak var name: Type! = nil

Xcode 会更改它并强制限制声明 @IBOutlet 非选项类型变量,因此遵循 @IBOutlet 的两种声明都是有效的。

@IBOutlet var outputLabel : UILabel!
@IBOutlet var priceLabel : UILabel?

但是,如果您在 beta 4 中控制拖动一个标签的插座,则会发生这种情况:

@IBOutlet var priceLabel : UILabel! = nil

【讨论】:

  • 谢谢!!所以我就说吧。这涵盖了教程方面......好吧
【解决方案2】:

界面构建器数据是在视图控制器启动后加载的,因此在初始化后插座不能有值。使用隐式展开的可选属性(在这种情况下为插座),您可以保证在对象启动后属性可能为 nil,但它们的值将在稍后(在加载 nib 或情节提要之后)分配。

【讨论】:

    【解决方案3】:

    没错。在 Swift 中,X 类型的变量不能为 nil,这意味着它必须被初始化。这意味着您必须在 init 方法或内联初始化中进行初始化。

    通常,视图控制器将声明可选类型的变量 - 例如,

    @IBOutlet var outputLabel : UILabel!

    这意味着您不需要初始化outputLabel,默认情况下,它的值是nil。这是IBOutlet 变量的一般模式,因为变量是在init 方法之外设置的。

    如果您不将变量设为可选,则必须对其进行初始化。如果你不初始化内联,你必须提供一个 init 方法 - 因此你得到的错误。

    【讨论】:

    • 如何在 swift 中提供初始化?
    • 您需要查看视图控制器并覆盖init 方法之一。例如,您在这里有一个: required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
    • 提供一个初始化器是没有抓住重点。出口不会在初始化时填充,它们会在视图加载时填充,并且在此之前将为零。
    【解决方案4】:

    由于 Stack 允许 Q 和 A 风格的问题,我也会用更简单的词来表达。只需将! 放在网点处即可。非常感谢您的帮助。

    【讨论】:

      【解决方案5】:

      错误

      'required' initialized 'init(coder:)' must be provided by subclass of 'UIViewController' 
      

      我加的时候突然开始

      var start : NSDate
      

      到以前工作的 UIViewController 子类,否则都是在 IB 中制作的。 改为

       var start : NSDate?
      

      已修复。这是一个令人惊讶的错误(嗯?初始化?编码器?)对于一个启动应用程序的人在遇到编码器或创建自己的初始化方法之前可能会进行的简单编辑,这可能有助于明确表明初始化需求不限于IB 奥特莱斯。上面的答案描述了根本原因。

      【讨论】:

        【解决方案6】:

        当从界面构建器文件初始化视图或视图控制器时,它们的出口还不能连接。它们只会在初始化后连接,因此它们需要是可选的。但是,当初始化后调用类中的任何其他代码时,可以保证这些出口是连接的。这就是为什么 IBOutlets 总是被声明为隐式展开的可选项。

        【讨论】:

          【解决方案7】:

          虽然 XCode 似乎支持这种行为,但它仍然是不安全的,您始终牢记您可能想要创建一些 Optional。

          虽然 IB 会为您初始化这些,但这并不能保证它们以后不会变为 nil ...例如,如果您需要将 IBOutlet 作为子视图删除,或者有条件地设置 NSLayoutConstraint.isActive = false (这是一个令人讨厌的隐秘零)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-02-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-13
            • 1970-01-01
            相关资源
            最近更新 更多