给定一个函数引用,Swift中有没有办法将该函数的名称作为适合传递给NSSelectorFromString
的字符串?
我希望将NSNotificationCenter
addObserver
包含一个带有函数引用而不是选择器字符串的版本:
addObserver(self, function: someCallback, name: "some notification", object: nil)
但是addObserver
接受一个String选择器参数。
答案 0 :(得分:4)
你正在重新发明一个不必要的轮子。 NSNotificationCenter 已经有一个观察方法,它接受一个函数(Objective-C调用"块"):
addObserverForName:object:queue:usingBlock:
所以就这样使用它。
答案 1 :(得分:0)
编辑:我将此留在这里是为了感兴趣,但这太复杂了(被问到如何问题,而不是目标)。除了现有的基于块的方法之外,还有this handy extension to it。
我不会这样做。它太有限了,因为它会排除函数文字(匿名函数)。
相反,我会玩这个游戏:[String: Void -> ()]
(字符串到函数)observer_dispatcher_<key>
(或您喜欢的任何前缀)。resolveInstanceMethod:
以动态创建您要求的任何observer_dispatcher_
方法。他们都可以指向相同的IMP
,例如:(假设这是好Swift;我还没试过):
void _observer_dispatcher(self: AnyObject, _cmd: Selector) {
let name = // strip the leading stuff off of _cmd
if let f = self.dispatchTable[name] {
f()
}
}
(这仍然很草率;我必须更多地考虑正确的错误,但这是我进入的方向。)
答案 2 :(得分:0)
我仍然希望找到原始问题的答案,但根据@ matt的建议,我目前正在使用此扩展程序:
extension NSNotificationCenter {
class func addObserver(function: (NSNotification!) -> (), name: String? = nil, object: AnyObject? = nil, queue: NSOperationQueue? = nil) {
defaultCenter().addObserverForName(name, object: object, queue: nil, usingBlock: function)
}
}
由于它隐式使用defaultCenter()
并提供了object
和queue
的默认值,我几乎总是将其传递为nil,因此可以进行更简洁的调用:
NSNotificationCenter.addObserver(doSomething, name: "some notification")
我喜欢它链接实际函数(doSomething
),而不是字符串表示。它不是通用扩展,但我认为它覆盖了我注册通知的90%的情况。