在objective-c中,我们有一个-forwardInvocation:可以像这样使用:
-(void)forwardInvocation:(NSInvocation*) anInvocation{
BOOL didForward = NO;
//iterate over our proxied objects
for(id proxyObject in self.proxyObjects){
//invoke the with the proxy object if it can handle the selector
if ([proxyObject respondsToSelector:[anInvocation selector]]){
didForward = YES;
[anInvocation invokeWithTarget: proxyObject];
}
}
//if we did not forward the invocation, then call super
if(!didForward){
[super forwardInvocation: anInvocation];
}
}
如果您有一组所有需要相同消息的具体类,这将非常有用。例如,如果您要实现多个分析平台,每个平台都需要相同的消息,但会以不同的方式处理它们。
考虑到我们对语言的了解,让我们快速做到这一点。这开始很简单:
func doSomething1(){
for proxyObject in proxyObjects{
proxyObject.doSomething1()
}
}
然后重复:
func doSomething2(){
for proxyObject in proxyObjects{
proxyObject.doSomething2()
}
}
func doSomething3(){
for proxyObject in proxyObjects{
proxyObject.doSomething3()
}
}
func doSomething4(){
for proxyObject in proxyObjects{
proxyObject.doSomething4()
}
}
....And on and on
我知道我可以在swift中使用NSObject,但那只是在我们需要它的Objective-c中混合。什么是一种更有效,更简洁的方法来处理纯粹的快速?
答案 0 :(得分:2)
Swift的设计是为了远离这种设计模式。没有ObjC这样的动态消息传递。必须在编译时知道每个方法。在纯粹的Swift中没有真正的替代品。但是我们可以通过使用Swift的闭包来模拟(在有限的程度上)ObjC运行时所做的事情:
typealias MyAction = () -> Void
enum ValidActions {
case Hello
case Goodbye
}
protocol MyProxyProtocol {
var actions : Dictionary<ValidActions, MyAction> { get }
}
private class Concrete1 : MyProxyProtocol {
var actions = Dictionary<ValidActions, MyAction>()
init() {
self.actions[.Hello] = helloWorld
self.actions[.Goodbye] = goodbyeWorld
}
func helloWorld() -> Void {
print("Hello world from concrete 1")
}
func goodbyeWorld() -> Void {
print("Goodbye world from concrete 1")
}
}
private class Concrete2 : MyProxyProtocol {
var actions = Dictionary<ValidActions, MyAction>()
init() {
self.actions[.Hello] = hello
}
func hello() -> Void {
print("Hi from concrete 2")
}
}
public class AbstractClass {
var proxyObjects = [MyProxyProtocol]()
init() {
self.proxyObjects.append(Concrete1())
self.proxyObjects.append(Concrete2())
}
func performAction(action : ValidActions) {
for proxy in self.proxyObjects {
if let f = proxy.actions[action] {
f()
}
}
}
}
let x = AbstractClass()
x.performAction(.Hello) // Both concrete classes will do this
x.performAction(.Goodbye) // Only the first one will do this
每个具体类通过actions
字典公开它可以处理的动作。处理它们的函数存储为内部的闭包。