2016-11-06 107 views
2

來自.Net,我想學習Swift3/iOS,並且對可選協議成員的以下明顯不一致的行爲感到困惑。我懷疑它與objc/swift之間的雜耍有關,但我在這裏錯過了什麼?Swift可選協議行爲不一致

// In playground, given below: 

@objc protocol SomePtotocol { 
    @objc optional func someMethod() 
} 

class SomeDelegate: NSObject, SomePtotocol { 
} 

class SomeController: NSObject { 
    var delegate: SomePtotocol = SomeDelegate() 
} 

// This works and compiles without error 

let controller = SomeController() 
controller.delegate.someMethod?()  // No error, typed as '(() ->())?' 

// But this fails to even compile ?? 

let delegate = SomeDelegate() 
delegate.someMethod?() // Error: 'SomeDelegate' has no member 'someMethod' 

我期望無論是失敗或兩者都通過,所以如果有人可以請賜教我這個異常。

+0

如果你正在學習iOS和Swift,那麼我的建議是**不使用'@ objc'和'NSObject'。除非你嘗試去做一些結構不能做的事情,否則''''''''''更好。同樣,更喜歡'讓'變成'var'。這段代碼根本不是Swifty。 – KPM

+0

我確實知道swift喜歡在類上構建結構,但不幸的是,另一個概念領域是我正在努力將自己的頭部包裹在.Net中,我被教導喜歡使用類而不是結構。 –

回答

1

兩段代碼之間的區別是所涉及變量的類型。

在第一個塊中,delegate明確鍵入爲SomePtotocol,並且此協議定義someMethod方法,因此您的語句是有效的。

在第二塊,delegate被隱式類型爲SomeDelegate,雖然這個類符合SomePtotocol,它沒有實現的可選方法someMethod,所以你得到一個錯誤。

如果你改變你的第二塊

let delegate: SomePtotocol = SomeDelegate() 
delegate.someMethod?() 

這相當於第一個塊,那麼就沒有錯誤。

+0

很好解釋,確實有道理 - 謝謝 –