zoukankan      html  css  js  c++  java
  • [Objective-C]用Block实现链式编程

    看这篇博客时最快让你上手ReactiveCocoa之基础篇看到作者介绍链式编程那一块,发现自己的钻研精神不足。想想自己使用链式编程也有段时间了,对,就是 Masonry 库。自己一直享受点语法带来的效率提升,却没想过自己去照着实现一下,真是惭愧。

    好吧,本着发现问题就要立即解决问题的一贯原则,就看一看链式语法的实现方法。

    现在做一个加减乘除计算。

    在 Masonry 里,我们常用的添加约束的方法就是 mas_makeConstraints:

    // View+MASAdditions
    - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
        self.translatesAutoresizingMaskIntoConstraints = NO;
        MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
        block(constraintMaker);
        return [constraintMaker install];
    }
    

    在约束里,用到 left, right 等是 constraintMaker 的属性,最后设置参数,比如 offset() 是 MASConstraint 的方法:

    //MASConstraintMaker
    @property (nonatomic, strong, readonly) MASConstraint *left;
    
    - (MASConstraint *)left {
        return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
    }
    
    //MASConstraint
    - (MASConstraint * (^)(CGFloat offset))offset;
    
    - (MASConstraint * (^)(CGFloat))offset {
        return ^id(CGFloat offset){
            self.offset = offset;
            return self;
        };
    }
    

    所以源码大概的结构是这样。然后就要实现我们的计算器了。

    //NSObject+Extension
    @implementation NSObject (Calculator)
    
    - (CGFloat)makeCalculators:(void (^)(CalculatorMaker *))block {
        CalculatorMaker *mgr = [[CalculatorMaker alloc] init];
        
        block(mgr);
        
        return mgr.result;
    }
    
    @end
    
    //CalculatorMaker.h
    @interface CalculatorMaker : NSObject
    
    @property (nonatomic, assign) int result;
    
    - (CalculatorMaker *(^)(int)) add;
    - (CalculatorMaker *(^)(int)) sub;
    - (CalculatorMaker *(^)(int)) mul;
    - (CalculatorMaker *(^)(int)) div;
    
    @end
    
    
    //CalculatorMaker.m
    @implementation CalculatorMaker
    
    - (CalculatorMaker *(^)(int))add {
        return ^CalculatorMaker *(int value) {
            _result += value;
            return self;
        };
    }
    
    - (CalculatorMaker *(^)(int))sub {
        return ^CalculatorMaker *(int value) {
            _result -= value;
            return self;
        };
    }
    
    - (CalculatorMaker *(^)(int))mul {
        return ^CalculatorMaker *(int value) {
            _result *= value;
            return self;
        };
    }
    
    - (CalculatorMaker *(^)(int))div {
        return ^CalculatorMaker *(int value) {
            _result /= value;
            return self;
        };
    }
    
    @end
    
    //main.m
    int result = [NSObject makeCalculators:^(CalculatorMaker *make) {
              make.add(1).add(5).mul(2);
            }];
    //output 12
    

    看 add() 方法,返回类型是自身所在 CalculatorMaker 类型的 Block,而 Block 返回的也是 self,所以可以连续使用链式调用。不过关于为什么可以用点语法,这个我有点晕,按说 make.add 是 OC 语法,后面括号跑到 Block 里去。那对于 OC 语法来说,点语法是针对 getter 方法的,对于没有参数的非 getter 方法也可以调用,但调用时会报 warning ,所以这点不是很懂。

    关于链式调用的写法,有点秀技术的感觉。视情况而用。不过,鉴于 Masonry 作者能写出这么有技巧的代码,我觉得有必要研究一下 Masonry 源码了。

  • 相关阅读:
    学习进度条
    学术诚信与职业道德
    czxt
    操作系统
    04 17评论博客
    0414 结对 2.0 33 34
    0408 汉堡包
    (补)结对心得
    构建之法4读后感
    复利计算4.0
  • 原文地址:https://www.cnblogs.com/rossoneri/p/5630933.html
Copyright © 2011-2022 走看看