想要避免为 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写这段代码就更好了,就是为了这种动态转发而生的。你可以变得更加优雅。但我不会描述您如何做到这一点,因为这会使我们与您的要求相去甚远。