美文网首页
Swift Target-Action、Curring 设计模式

Swift Target-Action、Curring 设计模式

作者: GUIYIVIEW | 来源:发表于2022-11-04 09:32 被阅读0次

    自定义实现类似UIButtonaddTarget事件响应链

    沿用OC调用方式

    动态调用

    声明

        weak var target: AnyObject?;
        var action: Selector?;
        func addTarget(_ target: AnyObject, selector: Selector) {
            self.target = target;
            self.action = selector;
        }
    

    调用

        if let target = target, let selector = action {
            if let method = class_getInstanceMethod(type(of: target), selector) {
                let imp = method_getImplementation(method);
                typealias Function = @convention(c) (AnyObject, Selector, Any?) -> ();
                let function = unsafeBitCast(imp, to: Function.self);
                function(target, selector, self);
            }
        }
    
    Swift Curring柯里化方式

    声明

    protocol TargetAction {
        func performAction();
    }
    
    struct TargetActionWrapper<T: AnyObject>: TargetAction {
        weak var target: T?;
        let action: (T) -> () -> ();
        
        func performAction() {
            if let t = target {
                action(t)();
            }
        }
    }
    
    class Model: NSObject {
        var wrapper: TargetAction?
        func addTarget<T: AnyObject>(target: T, action: @escaping (T) -> () -> ()) {
             wrapper = TargetActionWrapper(target: target, action: action);
        }
        
        func invoke() {
            wrapper?.performAction();
        }
    }
    

    调用

    let model = Model();
    model.addTarget(target: self, action: Test.invokeAction);
    
    func invokeAction() {}
    

    上面方法无法传递参数,需要进一步扩展。扩展可以根据自己需要,此处只简单举例。

    protocol TargetAction {
        func performAction(_ userInfo: Any?);
    }
    
    struct TargetActionWrapper<T: AnyObject>: TargetAction {
        weak var target: T?;
        let action: (T) -> (Any?) -> ();
        
        func performAction(_ userInfo: Any?) {
            if let t = target {
                action(t)(userInfo);
            }
        }
    }
    
    class Model: NSObject {
        var wrapper: TargetAction?
        var userInfo: Any?;
        func addTarget<T: AnyObject>(target: T, action: @escaping (T) -> (Any?) -> (), userInfo: Any? = nil) {
            self.userInfo = userInfo;
             wrapper = TargetActionWrapper(target: target, action: action);
        }
        
        func invoke() {
            wrapper?.performAction(userInfo);
        }
    }
    
    // 调用
    let model = Model();
    model.addTarget(target: self, action: Test.invokeAction, userInfo: ["a": "b"]);
    
    func invokeAction(_ sender: Any) {}
    

    相关文章

      网友评论

          本文标题:Swift Target-Action、Curring 设计模式

          本文链接:https://www.haomeiwen.com/subject/ypuytdtx.html