Ios 为什么UIKit没有';我不喜欢Swift 3选项?
以下Swift 3代码崩溃。通过删除显式可选类型或强制展开Ios 为什么UIKit没有';我不喜欢Swift 3选项?,ios,swift,uikit,optional,Ios,Swift,Uikit,Optional,以下Swift 3代码崩溃。通过删除显式可选类型或强制展开视图,可以轻松解决崩溃问题。有人能解释一下这段代码崩溃的原因吗 let view: UIView? = UIView() // note the explicit *optional* type _ = NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplie
视图
,可以轻松解决崩溃问题。有人能解释一下这段代码崩溃的原因吗
let view: UIView? = UIView() // note the explicit *optional* type
_ = NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: 44.0)
注意:它不会使用Swift 2.3或更低版本编译NSLayoutConstraint(项:,属性:,关联者:,toItem:,属性:,乘数:,常数:)
有一个项
参数键入为任何:
public convenience init(item view1: Any, attribute attr1: NSLayoutAttribute, relatedBy relation: NSLayoutRelation, toItem view2: Any?, attribute attr2: NSLayoutAttribute, multiplier: CGFloat, constant c: CGFloat)
但从崩溃中可以看出,该参数实际上只能接受UIView
或UILayoutGuide
:
由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“NSLayoutConstraint for Optional(UIView:0x7fa0fbd06650;frame=(0;0 0);layer=CALayer:0x6080003BB60):约束项必须是UIView或UILayoutGuide的实例
编译器无法在编译时检查项的类型。它被定义为接受任何东西。但是在我们无法访问的实现细节中,该方法只接受非可选的UIView
s或UILayoutGuide
s
因此,只需添加一个guard
语句:
let view: UIView? = UIView()
guard let view = view else { // Proceed only if unwrapped
fatalError()
}
let _ = NSLayoutConstraint(item: view, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: 44.0)
它崩溃的原因是UIView
和UIView?
是完全不同的类型UIView
是Objective-C类,而UIView?
是Swift枚举,可以包含UIView
。相反,在Objective-C中,可为null的
只是对编译器的一个提示。此代码不会崩溃。它无法编译。啊,我看到你在Swift 3中这样做了。在Swift 2中,第一个参数是AnyObject
(但不是AnyObject?
,就像item2
是一样),如果您传递了可选的。现在是Any
(不是Any?
像item2
)。编译器显然没有警告我们第一个参数不应该是可选的。但是它不能是可选的,而且当你试图通过可选的时,显然不喜欢它。是的,我指的是Swift 3(Xcode 8)。在报告中添加了注释question@Rob你知道有什么文件可以解释期权是如何实际实施的吗?我过去认为可选的只是编译时检查,就像ObjC中的\uu nullable
,但它看起来不是。@Alexandervassenin我知道了,但我们如何才能阻止由于这个原因而导致的崩溃?@Steve你必须打开可选的才能与UIKit一起使用它