Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional can only be applied to members of an @objc protocol

Here I define a protocol in Swift:

protocol DrawViewProtocol: class{
    optional func drawViewDidEndEditing() // Warning!
}

And Compiler gave me an error.

Optional can only be applied to members of an @objc protocol

So what I understand is optional and required are only avaliable in Objective-C? Though, how to define a optional or required in pure Swift style ?

like image 518
Zigii Wong Avatar asked Jun 22 '15 11:06

Zigii Wong


2 Answers

Swift doesn't allow protocols to have optional requirements-- if the protocol declares something, it's required. Objective-C has long had the idea of optional requirements, and Swift recognizes this when you use @objc when declaring the protocol. So using @objc is the easy way to get what you're after.

If you want a pure Swift solution, you need to add a protocol extension that includes default implementations of the methods. This doesn't make those methods optional, instead it says that any class that doesn't implement the method itself will use the default implementation instead. They're sort of optional in that classes don't have to implement them, but not really optional since that's only because a default implementation is available.

That would look something like this:

protocol DrawViewProtocol : class{
    func drawViewDidEndEditing()
}

extension DrawViewProtocol {
    func drawViewDidEndEditing() {}
}

class MyClass : DrawViewProtocol {

}

class MyOtherClass : DrawViewProtocol {
    func drawViewDidEndEditing() {
        print("Foo")
    }
}

Now if I create an instance of MyClass and call drawViewDidEndEditing(), it uses the default implementation, which does nothing. If I create an instance of MyOtherClass, the same method call prints "Foo".

like image 73
Tom Harrington Avatar answered Sep 25 '22 22:09

Tom Harrington


In Swift 3 and Swift 4 use @objc for optional prototype

@objc protocol YourProtocolName: class {
    @objc optional func yourMethodName()
}
like image 37
AkBombe Avatar answered Sep 26 '22 22:09

AkBombe