What is the Swift equivalent of respondsToSelector?


In Swift, the equivalent of the Objective-C method respondsToSelector is the responds property of the NSObject class.

To check if an object responds to a particular selector, you can use the responds(to:) method which is declared in the NSObjectProtocol. Here's the syntax −

if objectName.responds(to: #selector(methodName)) {
   // do something if the object responds to methodName
} else {
   // do something else if the object doesn't respond to methodName
}

In this syntax, objectName is the object that you want to check, and methodName is the selector that you want to check for. If objectName responds to methodName, the code inside the if block will be executed. If objectName does not respond to methodName, the code inside the else block will be executed.

Why @objc attribute required?

To use the responds(to:) method in Swift, you need to mark the class that contains the method you want to check with the @objc attribute. This attribute tells the Swift compiler to expose the method to the Objective-C runtime, allowing you to use the responds(to:) method.

Example 1

The responds(to:) method is a protocol method defined in the NSObjectProtocol. This means that any class that inherits from NSObject (which is the base class for most Objective-C and Swift classes) can use this method.

Step 1 − In this example, a class Person is defined that inherits from NSObject..Then an instance of a Person called amitObject is created.

Step 2 − We want to check if amitObject responds to the displayDetails method. To do this, we use the #selector syntax to create a selector for the displayDetails method, and then pass this selector to the responds(to:) method of amitObject.

Step 3 − If amitObject responds to displayDetails, the code inside the if block will be executed and the output will be "Object amit responds to the displayDetails method". If amitObject does not respond to displayDetails, the code inside the else block will be executed and the output will be "Object amit does not respond to the displayDetails method".

Here's an example of how to use responds(to:) in Swift −

class Person: NSObject {
    
   var name: String
   var age: Int
    
   init(name: String, age: Int) {
      self.name = name
      self.age = age
   }
    
   @objc func displayDetails() {
      print("Name: \(self.name) and age: \(self.age)")
   }
}
let amitObject = Person(name: "Amit", age: 25)
if amitObject.responds(to: #selector(Person.displayDetails)) {
   print("Object amit responds to the displayDetails method")
} else {
   print("Object amit does not respond to the displayDetails method")
}

Output

Object amit responds to the displayDetails method

Example 2

In this example, we will create a class named Person. The Person class does not inherit from NSObject and defines a method displayDetails. Here is the complete example −

class Person {
    
   var name: String
   var age: Int
    
   init(name: String, age: Int) {
      self.name = name
      self.age = age
   }
    
func displayDetails() {
      print("Name: \(self.name) and age: \(self.age)")
   }
}
let amit = Person(name: "Amit", age: 25)
if amit.responds(to: #selector(Person.displayDetails)) {
   print("Object amit responds to displayDetails method.")
} else {
   print("Object amit does not respond to displayDetails method.")
}

Output

value of type 'Person' has no member 'responds'

Example 3

In this example, we will check if an object responds to a protocol method.

Step 1 − In this example, we define a protocol PersonManager with a method displayDetails. We also define a class Person that conforms to PersonManager and implements displayDetails. We create an instance of a Person called amit.

Step 2 − We use responds(to:) to check if amit responds to displayDetails as defined in PersonManager. If amit responds to displayDetails, we use the perform(_:) method to call displayDetails.

Step 3 − We pass the selector #selector(PersonManager.displayDetails) to responds(to:) and perform(_:) instead of #selector(Person.displayDetails). This is because we want to check if amit responds to the displayDetails method as defined in the PersonManager protocol, not just as implemented in Person.

@objc protocol PersonManager {
    @objc func displayDetails()
}
class Person: NSObject, PersonManager {
    
   var name: String
   var age: Int
    
   init(name: String, age: Int) {
      self.name = name
      self.age = age
   }
    
   func displayDetails() {
      print("Name: \(self.name) and age: \(self.age)")
   }
}
let amit = Person(name: "Amit", age: 25)
if amit.responds(to: #selector(PersonManager.displayDetails)) {
   print("Object amit responds to displayDetails method")
} else {
   print("Object amit does not respond to displayDetails method")
}

Output

Object amit responds to displayDetails method

Conclusion

In Swift, we have the @objc attribute to expose classes, structs, enums, properties, methods, and other entities to Objective-C code.

The responds(to:) method is used to check whether an object can respond to a given selector or not, which is essentially a method name.

Updated on: 11-Apr-2023

628 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements