我在谷歌上搜索了一下,但没有找到与respondsToSelector:等价的swift:是什么。

这是我唯一能找到的(Swift替代respondsToSelector),但在我的情况下并不太相关,因为它检查委托的存在,我没有委托,我只是想检查在设备上运行时是否存在新的API,如果没有回落到API的以前版本。


当前回答

在Swift 2中,苹果引入了一个叫做API可用性检查的新功能,它可能是respondsToSelector:方法的替代品。下面的代码片段比较摘自WWDC2015第106次会议“Swift有什么新”,我想这可能会对你有所帮助,如果你需要了解更多,请查看。

老方法:

@IBOutlet var dropButton: NSButton!
override func awakeFromNib() {
    if dropButton.respondsToSelector("setSpringLoaded:") {
        dropButton.springLoaded = true
    }
}

更好的方法:

@IBOutlet var dropButton: NSButton!
override func awakeFromNib() {
    if #available(OSX 10.10.3, *) {
        dropButton.springLoaded = true
    }
}

其他回答

对于swift3

如果您只想调用该方法,请运行下面的代码。

self.delegate .method ? ()

斯威夫特3:

协议

@objc protocol SomeDelegate {
    @objc optional func method()
}

对象

class SomeObject : NSObject {

weak var delegate:SomeObject?

func delegateMethod() {

     if let delegateMethod = delegate?.method{
         delegateMethod()
     }else {
        //Failed
     }

   }

}

没有真正的Swift替代品。

您可以通过以下方式进行检查:

someObject.someMethod?()

只有当someemethod方法定义在对象someObject上时,才会调用它,但你只能将它用于已声明该方法为可选的@objc协议。

Swift本质上是一种安全的语言,所以每次你调用一个方法时,Swift都必须知道这个方法在那里。不可能进行运行时检查。你不能对随机对象调用随机方法。

即使在Obj-C中,你也应该尽可能避免这样的事情,因为它不能很好地使用ARC (ARC会触发performSelector的警告:)。

然而,当检查可用的api时,你仍然可以使用respondsToSelector:,即使是Swift,如果你正在处理NSObject实例:

@interface TestA : NSObject

- (void)someMethod;

@end

@implementation TestA

//this triggers a warning

@end   

var a = TestA()

if a.respondsToSelector("someMethod") {
   a.someMethod()
}

如果你要测试的方法在@objc协议中被定义为可选方法(听起来像你的情况),那么使用可选的链接模式为:

if let result = object.method?(args) {
  /* method exists, result assigned, use result */
}
else { ... }

当方法被声明为返回Void时,只需使用:

if object.method?(args) { ... }

See:

通过可选链接调用方法 摘自:苹果公司《快速编程语言》。 iBooks。https://itun.es/us/jEUH0.l

我使用guard let else,如果委托func没有实现,它可以做一些默认的事情。

@objc protocol ViewController2Delegate: NSObjectProtocol {

    optional func viewController2(controller: ViewController2, didSomethingWithStringAndReturnVoid string: String)

    optional func viewController2(controller: ViewController2, didSomethingWithStringAndReturnString string: String) -> String
}

class ViewController2: UIViewController {

    weak var delegate: ViewController2Delegate?        

    @IBAction func onVoidButtonClicked(sender: AnyObject){

        if (delegate != nil && delegate!.respondsToSelector(Selector("viewController2:didSomethingWithStringAndReturnVoid:"))) {
            NSLog("ReturnVoid is implemented")

            delegate!.viewController2!(self, didSomethingWithStringAndReturnVoid: "dummy")
        }
        else{
            NSLog("ReturnVoid is not implemented")
            // Do something by default
        }
    }

    @IBAction func onStringButtonClicked(sender: AnyObject){

        guard let result = delegate?.viewController2?(self, didSomethingWithStringAndReturnString: "dummy") else {
            NSLog("ReturnString is not implemented")
            // Do something by default
            return
        }

        NSLog("ReturnString is implemented with result: \(result)")
    }
}