Objective-C链式语法简单实现

最近了解了下OC的链式语法,跟我们平时[obj xxx]这种方法调用格式大相径庭。于是乎,自己也尝试着实现了如下调用方式:

    UIView *view = [UIView new];
    view.x.y.equalTo(5).with.w.h.equalTo(50);    

    NSLog(@"%@", NSStringFromCGRect(view.frame));

输出:{{5, 5}, {50, 50}}

完整Demo在这里:https://github.com/xiaoxm/ObjCChainingTest

这里简单记录下每种写法的实现机制:

view.x

回忆下,通常我们可以这样写一般是因为有一个property,而property会自动获得getter、setter方法。看代码:

//声明property x
@property (nonatomic, assign) CGFloat x;

//于是自动获得如下方法,�且不需要自己手动再写一遍
- (void)setX:(CGFloat)x;
- (CGFloat)x;

view.x会解析为调用方法- (CGFloat)x;。同理,如果想要支持view.x这种调用方式,只需要添加方法- (CGFloat)x;即可。

view.x.y

- (CGFloat)x;�修改为- (UIView *)x;。这样,view.x执行后返回值仍旧为view对象,点语法继续调用,等同于view.xview.y这两步。

view.equalTo(5)

首先我们来看下block的基本使用:

    //例1
    void (^block)() = ^(){
        NSLog(@"无参数,无返回值");
    };
    block();

    //例2
    void (^block)(int) = ^(int val){
        NSLog(@"仅参数:%d", val);
    };
    block(5);

    //例3
        int (^block)() = ^(){
            return 5;
        };
        NSLog(@"仅返回值:%d", block());

    //例4
    int (^block)(int) = ^(int val){
        return val + 1;
    };
    NSLog(@"有参数,有返回值:%d", block(5));

我们观察block的调用方式:block();是不是有些启发了呢?
view.equalTo()可以这么理解:view.equalTo获取到一个block,然后末尾加上()便是调用这个block了。
于是乎,定义一个返回值为block的方法- (void (^)())equalTo;便可以这样调用view.equalTo();
这里还需要一个输入参数,简单,修改block就好:- (void (^)(CGFloat))equalTo;。于是最终调用便有了:view.equalTo(5)

以上,祝大家玩得开心~

你可能感兴趣的:(Objective-C链式语法简单实现)