ios - 为什么 Swift4 会转换一个 UIButton 数组!到 [UIButton?] 类型?

标签 ios swift swift4

今天遇到一个奇怪的问题。请看这段代码:

class A {

    var button1: UIButton!
    var button2: UIButton!

    func foo() {
        let array = [button1, button2]
    }
}

Xcode 表示 array[UIButton?] 类型。出于某种原因,Swift4 将 UIButton! 元素转换为 UIButton?。为什么?

最佳答案

解释

ImplicitlyUnwrappedOptional不是一个独特的类型,而是一个普通的 Optional声明其值的属性可能会被隐式强制(基于 SE-0054 ):

However, the appearance of ! at the end of a property or variable declaration's type no longer indicates that the declaration has IUO type; rather, it indicates that (1) the declaration has optional type, and (2) the declaration has an attribute indicating that its value may be implicitly forced. (No human would ever write or observe this attribute, but we will refer to it as @_autounwrapped.) Such a declaration is referred to henceforth as an IUO declaration.

因此当你使用它时:

let array = [button1, button2]

编译器导出 array输入 [UIButton?] , 因为 button1 的类型和 button2Optional<UIButton> , 不是 ImplicitlyUnwrappedOptional<UIButton> (即使只有一个按钮是可选的,它也会派生出可选类型)。

阅读更多 SE-0054 .

旁注:

此行为与arrays 没有真正相关, 在以下示例中 button2 的类型将派生到 UIButton?即使有 ! button 中设置了一个值:

var button: UIButton! = UIButton()

func foo() {
    let button2 = button // button2 will be an optional: UIButton?
}

解决方案

如果你想得到一个解包类型的数组,你有两个选择:

首先,如Guy Kogus在他的回答中建议,使用显式类型而不是让 swift 派生它:

let array: [UIButton] = [button1, button2]

但是,如果碰巧其中一个按钮包含 nil ,它会导致Unexpectedly found nil崩溃。

虽然通过使用隐式展开的可选而不是可选(! 而不是 ?)你声称这些按钮中永远不会有 nil,但我仍然更喜欢第二个更安全的选项EmilioPelaez 建议在他的评论中。即使用flatMap ( compactMap 在 Swift 4+ 中)将过滤掉 nil s,如果有的话,将返回一个未包装类型的数组:

let array = [button1, button2].flatMap { $0 }

关于ios - 为什么 Swift4 会转换一个 UIButton 数组!到 [UIButton?] 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54054433/

相关文章:

ios - Swift:如何在同步方法中包装异步方法?

ios - SwiftUI - NavigationBar 未显示在 Modal NavigationView 中

iphone - 带有 UIpagecontroller 的 UIActionsheet

swift - 二元运算符 '+' 不能应用于类型 'Int' 和 '[Int]' 的操作数

ios - 如何让TextView可以水平滚动

ios - 仅在 iOS 13 上运行时出现日期格式错误

ios - 在 Swift 中渲染 MKPolyline

ios - 以编程方式创建 UIButton 时启用色调颜色更改动画

ios - 检索等于 UUID 的 Realm 对象

swift - 如何使用 Xcode 对象库为 Cocoa Swift 构建插入删除表单?