想要避免为 Swift 2 委托调度程序复制粘贴方法名称
Want to avoid copy-pasting method names for a Swift 2 delegate dispatcher
我正在尝试实现一个调度程序来通知委托模式协议的多个目标。
执行以下模式的更好方法是什么,而无需为每个方法名称复制粘贴?反射、面向切面编程、元编程都想到了:
public class AirBatteryClientDelegateDispatcher: AirBatteryClientDelegate {
private var targets = [AirBatteryClientDelegate]()
public func clientDidStartScan(client: AirBatteryClient) {
for target in targets {
target.clientDidStartScan?(client)
}
}
. . .
}
作为参考,我使用了以下协议和十几种类似的方法:
@objc public protocol AirBatteryClientDelegate: class {
optional func clientDidStartScan(client: AirBatteryClient)
optional func clientDidStopScan(client: AirBatteryClient)
optional func clientDidUpdateState(client: AirBatteryClient)
. . .
}
您将必须显式实现所有委托方法,但至少可以通过以相同方式实现它们来减少重复次数。实际上,由于您正在使用 Objective-C 功能(可选协议方法),因此您正在编写此代码 in Objective-C:
@objc protocol AirBatteryClientDelegate: NSObjectProtocol { // *
optional func clientDidStartScan(client: AirBatteryClient)
optional func clientDidStopScan(client: AirBatteryClient)
optional func clientDidUpdateState(client: AirBatteryClient)
}
class AirBatteryClientDelegateDispatcher {
private var targets = [AirBatteryClientDelegate]()
private func call(f:String, client:AnyObject) {
for target in targets {
let f = f + ":" // work around Swift bug
if target.respondsToSelector(Selector(f)) {
target.performSelector(Selector(f), withObject:client)
}
}
}
func clientDidStartScan(client: AirBatteryClient) {
call(#function, client:client) // or __FUNCTION__ before Swift 2.2
}
// ... and the others are identical
}
不过,如果你真的是在Objective-C写这段代码就更好了,就是为了这种动态转发而生的。你可以变得更加优雅。但我不会描述您如何做到这一点,因为这会使我们与您的要求相去甚远。
我正在尝试实现一个调度程序来通知委托模式协议的多个目标。
执行以下模式的更好方法是什么,而无需为每个方法名称复制粘贴?反射、面向切面编程、元编程都想到了:
public class AirBatteryClientDelegateDispatcher: AirBatteryClientDelegate {
private var targets = [AirBatteryClientDelegate]()
public func clientDidStartScan(client: AirBatteryClient) {
for target in targets {
target.clientDidStartScan?(client)
}
}
. . .
}
作为参考,我使用了以下协议和十几种类似的方法:
@objc public protocol AirBatteryClientDelegate: class {
optional func clientDidStartScan(client: AirBatteryClient)
optional func clientDidStopScan(client: AirBatteryClient)
optional func clientDidUpdateState(client: AirBatteryClient)
. . .
}
您将必须显式实现所有委托方法,但至少可以通过以相同方式实现它们来减少重复次数。实际上,由于您正在使用 Objective-C 功能(可选协议方法),因此您正在编写此代码 in Objective-C:
@objc protocol AirBatteryClientDelegate: NSObjectProtocol { // *
optional func clientDidStartScan(client: AirBatteryClient)
optional func clientDidStopScan(client: AirBatteryClient)
optional func clientDidUpdateState(client: AirBatteryClient)
}
class AirBatteryClientDelegateDispatcher {
private var targets = [AirBatteryClientDelegate]()
private func call(f:String, client:AnyObject) {
for target in targets {
let f = f + ":" // work around Swift bug
if target.respondsToSelector(Selector(f)) {
target.performSelector(Selector(f), withObject:client)
}
}
}
func clientDidStartScan(client: AirBatteryClient) {
call(#function, client:client) // or __FUNCTION__ before Swift 2.2
}
// ... and the others are identical
}
不过,如果你真的是在Objective-C写这段代码就更好了,就是为了这种动态转发而生的。你可以变得更加优雅。但我不会描述您如何做到这一点,因为这会使我们与您的要求相去甚远。