Swift 中 `respondsToSelector` 的等价方法是什么?


在 Swift 中,Objective-C 方法 `respondsToSelector` 的等价方法是 `NSObject` 类的 `responds` 属性。

要检查一个对象是否响应某个特定的选择器,可以使用 `responds(to:)` 方法,该方法在 `NSObjectProtocol` 中声明。语法如下:

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
}

在这个语法中,`objectName` 是要检查的对象,`methodName` 是要检查的选择器。如果 `objectName` 响应 `methodName`,则 `if` 代码块内的代码将被执行。如果 `objectName` 不响应 `methodName`,则 `else` 代码块内的代码将被执行。

为什么需要 `@objc` 属性?

要在 Swift 中使用 `responds(to:)` 方法,需要用 `@objc` 属性标记包含要检查的方法的类。此属性告诉 Swift 编译器将该方法暴露给 Objective-C 运行时,从而允许使用 `responds(to:)` 方法。

示例 1

`responds(to:)` 方法是在 `NSObjectProtocol` 中定义的协议方法。这意味着任何继承自 `NSObject` 的类(大多数 Objective-C 和 Swift 类的基类)都可以使用此方法。

步骤 1 - 在此示例中,定义了一个继承自 `NSObject` 的类 `Person`。然后创建了一个名为 `amitObject` 的 `Person` 实例。

步骤 2 - 我们想检查 `amitObject` 是否响应 `displayDetails` 方法。为此,我们使用 `#selector` 语法为 `displayDetails` 方法创建一个选择器,然后将此选择器传递给 `amitObject` 的 `responds(to:)` 方法。

步骤 3 - 如果 `amitObject` 响应 `displayDetails`,则 `if` 代码块内的代码将被执行,输出为“对象 amit 响应 displayDetails 方法”。如果 `amitObject` 不响应 `displayDetails`,则 `else` 代码块内的代码将被执行,输出为“对象 amit 不响应 displayDetails 方法”。

以下是如何在 Swift 中使用 `responds(to:)` 的示例:

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")
}

输出

Object amit responds to the displayDetails method

示例 2

在此示例中,我们将创建一个名为 `Person` 的类。`Person` 类不继承自 `NSObject` 并定义了一个方法 `displayDetails`。以下是完整的示例:

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.")
}

输出

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

示例 3

在此示例中,我们将检查一个对象是否响应协议方法。

步骤 1 - 在此示例中,我们定义了一个名为 `PersonManager` 的协议,其中包含一个方法 `displayDetails`。我们还定义了一个名为 `Person` 的类,该类符合 `PersonManager` 并实现了 `displayDetails`。我们创建了一个名为 `amit` 的 `Person` 实例。

步骤 2 - 我们使用 `responds(to:)` 来检查 `amit` 是否响应 `PersonManager` 中定义的 `displayDetails`。如果 `amit` 响应 `displayDetails`,我们使用 `perform(_:)` 方法来调用 `displayDetails`。

步骤 3 - 我们将选择器 `#selector(PersonManager.displayDetails)` 传递给 `responds(to:)` 和 `perform(_:)` 而不是 `#selector(Person.displayDetails)`。这是因为我们想要检查 `amit` 是否响应 `PersonManager` 协议中定义的 `displayDetails` 方法,而不仅仅是在 `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")
}

输出

Object amit responds to displayDetails method

结论

在 Swift 中,我们有 `@objc` 属性来将类、结构体、枚举、属性、方法和其他实体暴露给 Objective-C 代码。

`responds(to:)` 方法用于检查对象是否可以响应给定的选择器,该选择器本质上是一个方法名。

更新于:2023年4月11日

939 次浏览

开启你的 职业生涯

通过完成课程获得认证

立即开始
广告

© . All rights reserved.