加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

将相同的函数调用发送到多个对象的快捷方式是什么?

发布时间:2020-12-14 04:56:47 所属栏目:百科 来源:网络整理
导读:在 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
在 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中.什么是一种更有效,更简洁的方式来处理纯粹的快速?

解决方法

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

每个具体类都通过动作字典公开它可以处理的动作.处理它们的函数存储为内部的闭包.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读