2016-11-06 108 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

很好解释,确实有道理 - 谢谢 –