What is the Swift equivalent of respondsToSelector? What is the Swift equivalent of respondsToSelector? swift swift

What is the Swift equivalent of respondsToSelector?


As mentioned, in Swift most of the time you can achieve what you need with the ? optional unwrapper operator. This allows you to call a method on an object if and only if the object exists (not nil) and the method is implemented.

In the case where you still need respondsToSelector:, it is still there as part of the NSObject protocol.

If you are calling respondsToSelector: on an Obj-C type in Swift, then it works the same as you would expect. If you are using it on your own Swift class, you will need to ensure your class derives from NSObject.

Here's an example of a Swift class that you can check if it responds to a selector:

class Worker : NSObject{    func work() { }    func eat(food: AnyObject) { }    func sleep(hours: Int, minutes: Int) { }}let worker = Worker()let canWork = worker.respondsToSelector(Selector("work"))   // truelet canEat = worker.respondsToSelector(Selector("eat:"))    // truelet canSleep = worker.respondsToSelector(Selector("sleep:minutes:"))    // truelet canQuit = worker.respondsToSelector(Selector("quit"))   // false

It is important that you do not leave out the parameter names. In this example, Selector("sleep::") is not the same as Selector("sleep:minutes:").


There is no real Swift replacement.

You can check in the following way:

someObject.someMethod?()

This calls the method someMethod only if it's defined on object someObject but you can use it only for @objc protocols which have declared the method as optional.

Swift is inherently a safe language so everytime you call a method Swift has to know the method is there. No runtime checking is possible. You can't just call random methods on random objects.

Even in Obj-C you should avoid such things when possible because it doesn't play well with ARC (ARC then triggers warnings for performSelector:).

However, when checking for available APIs, you can still use respondsToSelector:, even if Swift, if you are dealing with NSObject instances:

@interface TestA : NSObject- (void)someMethod;@end@implementation TestA//this triggers a warning@end   


var a = TestA()if a.respondsToSelector("someMethod") {   a.someMethod()}


Update Mar 20, 2017 for Swift 3 syntax:

If you don't care whether the optional method exists, just call delegate?.optionalMethod?()

Otherwise, using guard is probably the best approach:

weak var delegate: SomeDelegateWithOptionals?func someMethod() {    guard let method = delegate?.optionalMethod else {        // optional not implemented        alternativeMethod()        return    }    method()}

Original answer:

You can use the "if let" approach to test an optional protocol like this:

weak var delegate: SomeDelegateWithOptionals?func someMethod() {  if let delegate = delegate {    if let theMethod = delegate.theOptionalProtocolMethod? {      theMethod()      return    }  }  // Reaching here means the delegate doesn't exist or doesn't respond to the optional method  alternativeMethod()}