迅速迁移5后为什么IBOutlets是可选的

时间:2019-03-29 17:40:49

标签: swift swift5

将项目迁移到Swift 5之后,我遇到了很多错误,例如

Expression implicitly coerced from 'UIButton?' to 'Any'

我不确定是什么原因造成的。我正在设置view.accessibilityElements时(发生一堆)的一个例子。该数组应该包含:[Any]?...知道是什么原因造成的吗?

这里是一个例子:

@IBOutlet weak var shareButton: UIButton!
@IBOutlet weak var shareTitleLabel: UILabel!

view.accessibilityElements = [shareButton, shareTitleLabel]

这里是另一个示例:

@IBOutlet weak var titleLabel: UILabel!

let titleConstraints = [
        NSLayoutConstraint(item: titleLabel, attribute: .leading, relatedBy: .equal, toItem: otherView, attribute: .leading, multiplier: 1, constant: horizontalTextInset),
        NSLayoutConstraint(item: titleLabel, attribute: .trailing, relatedBy: .equal, toItem: otherView, attribute: .trailing, multiplier: 1, constant: -horizontalTextInset)
]

像这样设置上面的元素时,会引起上述错误

1 个答案:

答案 0 :(得分:2)

一些观察结果:

  1. 引起问题的实际上不是迁移本身。问题只是因为您正在编译它Swift 5,现在它警告您有关模棱两可的强制。

    由于您没有共享产生此警告的确切代码,因此请考虑产生警告的示例:

    class ViewController: UIViewController {
    
        @IBOutlet var button: UIButton!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let foo: Any = button
            print(type(of: foo))
    
            // do something with `foo`
        }
    }
    

    因此,看一下这段代码,foo是可选的还是未包装的值?在Swift 5中,此警告将这种模糊性引起我们的注意

      

    警告:表达式从“ UIButton”隐式强制转换?到“任何”

    它将为您显示三个可能的自动修复程序,以消除这种歧义,即:

    • 使用nil-推销运算符??;
    • 强行打开包装,!;或
    • 只需使用as Any进行强制转换,即可明确地说出foo是可选的,无需解包。

    最重要的是,我们希望能够轻松地推断出我们的代码,而Any类型使得这一点变得模棱两可。编译器不再对您是否要解开button做出假设,而是要求我们明确我们的意图。

  2. 为便于比较,请考虑以下两种情况,其中没有歧义,因此没有警告。例如,考虑到相同的隐式展开的可选内容,在这里它知道应进行隐式展开:

    let foo: UIButton = button
    

    这里知道foo是可选的:

    let foo: UIButton? = button
    
  3. 如果您想知道为什么将您隐式解包的UIButton!出口根本被视为UIButton?(而不是ImplicitlyUnwrappedOptional类型,或者只是自动强制解开它,甚至尽管您使用的是Any类型,但在Reimplementation of Implicitly Unwrapped OptionalsSE-0054 Abolish ImplicitlyUnwrappedOptional type中有与此相关的有趣讨论。