可选只能应用于@objc协议的成员

时间:2015-06-22 11:47:06

标签: objective-c swift

这里我在Swift中定义了一个协议:

SERVICENAME__bgw.RunWorkerAsync()

编译器给了我一个错误。

  

可选只能应用于@objc协议的成员

所以我理解的是protocol DrawViewProtocol: class{ optional func drawViewDidEndEditing() // Warning! } optional只能在Objective-C中使用?但是,如何在纯Swift风格中定义可选必需

6 个答案:

答案 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中这样做的正确方法是实际使用协议:

  • 定义您的第一个协议A,只包含必需的属性,方法,......您可以将其命名为
  • 使用您所谓的“可选”属性
  • 定义第二个协议B.
  • 因此,您需要符合A标准的所有类/协议都将是。
  • 可以使用符合协议B的方式扩展需要“可选”合规性的那些。

示例:

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
}