2016-08-25 56 views
2

以下Swift 3代碼崩潰。通過刪除顯式的可選類型或強制解包view可以輕鬆解決崩潰問題。任何人都可以解釋爲什麼這段代碼崩潰了?爲什麼UIKit不喜歡Swift 3選項?

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) 

注:它不會與雨燕2.3或更低

+2

此代碼不會崩潰。它不會編譯。 – Rob

+1

啊,我看到你在Swift 3中這樣做了。在Swift 2中,第一個參數是'AnyObject'(但不是'AnyObject?',就像'item2'),並且如果你傳遞了一個可選參數,它會正確地提醒你。它現在是'Any'(不是'任何',比如'item2')。編譯器顯然不會警告我們,第一個參數不應該是可選的。但它不能是可選的,當你嘗試通過可選的時候顯然不喜歡它。 – Rob

+0

是的,我的意思是Swift 3(Xcode 8)。在問題中增加了註釋 –

回答

3

爲什麼它崩潰是UIViewUIView?是完全不同類型的原因。 UIViewObjective-C類,而UIView?快速枚舉它可以包含UIView。相反,Objective-C nullable只是編譯器的提示。

+0

我明白了,但是我們該如何設法停止因爲這個原因造成的崩潰? – Steve

+0

@Steve你必須打開可選的UIKit才能使用它 –

4

NSLayoutConstraint(item:, attribute:, relatedBy:, toItem:, attribute:, multiplier:, constant:)編譯具有item參數類型爲Any

public convenience init(item view1: Any, attribute attr1: NSLayoutAttribute, relatedBy relation: NSLayoutRelation, toItem view2: Any?, attribute attr2: NSLayoutAttribute, multiplier: CGFloat, constant c: CGFloat) 

但是從崩潰,你可以蒐集了參數只能接受UIViewUILayoutGuide

由於未捕獲異常'NSInvalidArgumentException'而終止應用程序,原因:'NSLayoutConstraint for Optional(UIView:0x7fa0fbd06650; frame =(0 0; 0 0); layer = CALayer:0x60800003bb60):約束條件必須每個項目都是UIView的一個實例,或者UILayoutGuide

編譯器在編譯期間無法檢查item的類型。它被定義爲接受任何東西。但是在我們無法實現的實現細節中,該方法只接受非可選的UIViewUILayoutGuide

所以只需添加一個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) 
相關問題