Gru*_*kes 189 objective-c selector swift
我用谷歌搜索,但无法找出快速等同于什么respondsToSelector:.
这是我唯一能找到的东西(Swift替代respondsToSelector :)但在我的情况下并不太重要,因为它检查委托的存在,我没有委托我只想检查是否存在新的API或者不在设备上运行时,如果没有回到以前版本的api.
Eri*_*rik 163
如上所述,在Swift中,大多数情况下,您可以通过?可选的unwrapper运算符实现所需的功能.这允许您在对象上调用方法,当且仅当对象存在(而不是nil)并且方法已实现时.
在您仍然需要的情况下respondsToSelector:,它仍然作为NSObject协议的一部分.
如果您respondsToSelector:在Swift 中调用Obj-C类型,那么它的工作方式与您期望的相同.如果您在自己的Swift类中使用它,则需要确保您的类派生自NSObject.
这是一个Swift类的示例,您可以检查它是否响应选择器:
class Worker : NSObject
{
func work() { }
func eat(food: AnyObject) { }
func sleep(hours: Int, minutes: Int) { }
}
let worker = Worker()
let canWork = worker.respondsToSelector(Selector("work")) // true
let canEat = worker.respondsToSelector(Selector("eat:")) // true
let canSleep = worker.respondsToSelector(Selector("sleep:minutes:")) // true
let canQuit = worker.respondsToSelector(Selector("quit")) // false
Run Code Online (Sandbox Code Playgroud)
重要的是不要遗漏参数名称.在这个例子中,Selector("sleep::")是不一样的Selector("sleep:minutes:").
Sul*_*han 59
没有真正的Swift替代品.
您可以通过以下方式办理登机手续:
someObject.someMethod?()
Run Code Online (Sandbox Code Playgroud)
someMethod只有在对象上定义了方法,才会调用该方法,someObject但只能将其用于@objc已声明方法的协议optional.
Swift本质上是一种安全的语言,所以每当你调用一个方法时,Swift必须知道方法就在那里.无法进行运行时检查.你不能只对随机对象调用随机方法.
即使在Obj-C中你也应该尽可能避免使用这些东西,因为它与ARC不能很好地结合(ARC会触发警告performSelector:).
但是,在检查可用的API时respondsToSelector:,即使是Swift,如果要处理NSObject实例,仍然可以使用:
@interface TestA : NSObject
- (void)someMethod;
@end
@implementation TestA
//this triggers a warning
@end
Run Code Online (Sandbox Code Playgroud)
var a = TestA()
if a.respondsToSelector("someMethod") {
a.someMethod()
}
Run Code Online (Sandbox Code Playgroud)
hyo*_*uuu 35
2017年3月20日更新Swift 3语法:
如果您不关心是否存在可选方法,只需调用即可 delegate?.optionalMethod?()
否则,使用guard可能是最好的方法:
weak var delegate: SomeDelegateWithOptionals?
func someMethod() {
guard let method = delegate?.optionalMethod else {
// optional not implemented
alternativeMethod()
return
}
method()
}
Run Code Online (Sandbox Code Playgroud)
原始答案:
您可以使用"if let"方法测试这样的可选协议:
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()
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*mar 11
您似乎需要将协议定义为NSObjectProtocol的子协议...然后您将获得respondsToSelector方法
@objc protocol YourDelegate : NSObjectProtocol
{
func yourDelegateMethod(passObject: SomeObject)
}
Run Code Online (Sandbox Code Playgroud)
请注意,仅指定@objc是不够的.你应该小心实际的委托是NSObject的子类 - 在Swift中可能不是.
GoZ*_*ner 10
如果要用于测试所述方法被定义为一个可选的方法中一个@objc协议(这听起来像您的情况下),然后使用可选链接模式为:
if let result = object.method?(args) {
/* method exists, result assigned, use result */
}
else { ... }
Run Code Online (Sandbox Code Playgroud)
当方法声明为返回时Void,只需使用:
if object.method?(args) { ... }
Run Code Online (Sandbox Code Playgroud)
看到:
"通过可选链接调用方法"
摘录自:Apple Inc."The Swift Programming Language."
iBooks.https://itun.es/us/jEUH0.l
函数是Swift中的第一类类型,因此您可以通过将它与nil进行比较来检查协议中定义的可选函数是否已实现:
if (someObject.someMethod != nil) {
someObject.someMethod!(someArgument)
} else {
// do something else
}
Run Code Online (Sandbox Code Playgroud)
在Swift 2中,Apple引入了一个名为的新功能API availability checking,它可能是respondsToSelector:方法的替代品.以下代码片段比较是从WWDC2015会话106中复制的.我认为Swift中的新功能可能对您有所帮助,如果您需要,请查看它知道更多.
旧方法:
@IBOutlet var dropButton: NSButton!
override func awakeFromNib() {
if dropButton.respondsToSelector("setSpringLoaded:") {
dropButton.springLoaded = true
}
}
Run Code Online (Sandbox Code Playgroud)
更好的方法:
@IBOutlet var dropButton: NSButton!
override func awakeFromNib() {
if #available(OSX 10.10.3, *) {
dropButton.springLoaded = true
}
}
Run Code Online (Sandbox Code Playgroud)
对于swift 3.0
import UIKit
@objc protocol ADelegate : NSObjectProtocol {
@objc optional func hi1()
@objc optional func hi2(message1:String, message2:String)
}
class SomeObject : NSObject {
weak var delegate:ADelegate?
func run() {
// single method
if let methodHi1 = delegate?.hi1 {
methodHi1()
} else {
print("fail h1")
}
// multiple parameters
if let methodHi2 = delegate?.hi2 {
methodHi2("superman", "batman")
} else {
print("fail h2")
}
}
}
class ViewController: UIViewController, ADelegate {
let someObject = SomeObject()
override func viewDidLoad() {
super.viewDidLoad()
someObject.delegate = self
someObject.run()
}
// MARK: ADelegate
func hi1() {
print("Hi")
}
func hi2(message1: String, message2: String) {
print("Hi \(message1) \(message2)")
}
}
Run Code Online (Sandbox Code Playgroud)
当我开始将旧项目更新到 Swift 3.2 时,我只需要将方法从
respondsToSelector(selector)
Run Code Online (Sandbox Code Playgroud)
到:
responds(to: selector)
Run Code Online (Sandbox Code Playgroud)