这里我在Swift中定义了一个协议:
SERVICENAME__bgw.RunWorkerAsync()
编译器给了我一个错误。
可选只能应用于@objc协议的成员
所以我理解的是protocol DrawViewProtocol: class{
optional func drawViewDidEndEditing() // Warning!
}
和optional
只能在Objective-C中使用?但是,如何在纯Swift风格中定义可选或必需?
答案 0 :(得分:31)
Swift不允许协议具有可选要求 - 如果协议声明了某些内容,则需要它。 Objective-C长期以来一直有可选要求的想法,当你在声明协议时使用@objc
时,Swift会认识到这一点。因此,使用@objc
是获取您之后的简单方法。
如果您需要纯Swift解决方案,则需要添加包含方法默认实现的协议扩展。这并不能使这些方法成为可选方法,而是说任何没有实现方法的类都将使用默认实现。它们是可选的,因为类不必实现它们,但不是真正可选的,因为这只是因为默认实现可用。
这看起来像这样:
protocol DrawViewProtocol : class{
func drawViewDidEndEditing()
}
extension DrawViewProtocol {
func drawViewDidEndEditing() {}
}
class MyClass : DrawViewProtocol {
}
class MyOtherClass : DrawViewProtocol {
func drawViewDidEndEditing() {
print("Foo")
}
}
现在,如果我创建MyClass
的实例并调用drawViewDidEndEditing()
,它将使用默认实现,它不执行任何操作。如果我创建MyOtherClass
的实例,则相同的方法调用会打印" Foo"。
答案 1 :(得分:15)
在 Swift 3 和 Swift 4 中使用 @objc 获取可选原型
@objc protocol YourProtocolName: class {
@objc optional func yourMethodName()
}
答案 2 :(得分:4)
来自Apple的文档:Even if you are not interoperating with Objective-C, you need to mark your protocols with the @objc attribute if you want to specify optional requirements.
请参阅this文档中的Optional Protocol Requirements section
。
答案 3 :(得分:4)
虽然以上答案实际正确,但它们并没有为您提供纯粹的Swift答案。
在Swift中这样做的正确方法是实际使用协议:
示例:强>
protocol MyRequiredProtocol {
var a: String { get }
var b: String { get }
func aMethod()
}
protocol MySoCalledOptionalProtocol {
var c: String { get }
func anotherMethod()
}
class MyFirstClass: MyRequiredProtocol {
var a: String { return "a" }
var b: String { return "b" }
func aMethod() {
// Do something
}
}
class MySecondClass: MyRequiredProtocol, MySoCalledOptionalProtocol {
var a: String { return "a" }
var b: String { return "b" }
var c: String { return "c" }
func aMethod() {
// Do something
}
func anotherMethod() {
// Do something
}
}
答案 4 :(得分:1)
你可以这样做:
@objc protocol MyProtocol {
optional func myMethod()
}
答案 5 :(得分:1)
在协议之前添加@objc 这样:
@objc protocol FriendsTableDelegate {
func didSelectFriend(friend: User) -> Void
optional func didSelectFriend(friend: User, cell: FriendCell) -> Void
}