Objc实现链式语法

最近在看文章的时候,了解到了各种编程思想。
以下来列举出常见的几种,以供学习
1. 面向过程 例如–> C语言
2. 面向对象 –> OC, JAVA .etc
3. 链式编程 –> Masonry, Javascript, JQuery .etc
4. 函数式编程 –> ReactiveCocoa

1和2,不再赘述。
4,ReactiveCocoa回头有时间了研究后再来写总结

这里来说下链式编程思想

借鉴了一些网上的资料,如有侵权,联系立删

简介

使用点(.)符号,来讲多行操作连接到一起的写法
例如:make.left.equalTo(view1);

语法特点

  • 返回值为block,且block返回值为对象本身
  • block中的参数,是我们需要操作的对象
    以这个例子来看
    exampleInstace.method1().method2();
  • 回想一下,OC里的点语法. 例如self.exampleInstance默认编译器会转化成getset方法。
  • method1()为声明一个block之后再调用它,然后要求返回值还是exampleInstance本身,这么一来,就可以继续使用点语法调用method2()了,以此来实现使用点语法连接各个各行语句。

所以 我们可以写一个计算器,来验证这个想法

实现如下
#import <Foundation/Foundation.h>

@interface Calculator : NSObject

@property (nonatomic,assign) int result;

@property (nonatomic,copy) Calculator *(^add)(int);

@property (nonatomic,copy) Calculator *(^subtract)(int);

@property (nonatomic,copy) Calculator *(^multiply)(int);

@property (nonatomic,copy) Calculator *(^devide)(int);

@end
#import "Calculator.h"

@implementation Calculator

- (instancetype)init {
    self = [super init];
    if (!self) {
        self = nil;
    }
    self.result = 0;
    return self;
}

- (Calculator *(^)(int))add {
    return ^id(int number){
        self.result += number;
        return self;
    };
}


- (Calculator *(^)(int))subtract {
    return ^id(int number) {
        self.result -= number;
        return self;
    };
}


- (Calculator *(^)(int))multiply {
    return ^id(int number) {
        self.result *= number;
        return self;
    };
}

- (Calculator *(^)(int))devide {
    return ^id(int number) {
        self.result /= number;
        return self;
    };
}


@end

log如下

    Calculator *cal = [[Calculator alloc]init];
    NSLog(@"%d",cal.add(18).result);

    2016-11-04 11:02:21.365 testLinkSyntax[1177:298419] 18

更简洁的实现

上面通过先声明类的一系列 Block 属性,再去实现 Block 属性的 getter 方法来实现链式调用,感觉还是有点啰嗦,有没有更简洁的实现方式呢?我们来看看 Objective-C 中点语法的本质

点语法的本质
点语法的本质1: 在 Objective-C 中,点语法实际上只是一种替换手段,对于属性的 getter 方法,class.xxx 的写法最终会被编译器替换成 [class xxx];对于 setter 方法,即把 class.xxx 写在等号左边,class.xxx = value 会被转换成 [class setXxx:value],本质上都是方法调用

点语法的本质2: 也就是说,即使在 class 中并没有显式声明 xxx 属性,在编译时,代码中如果有 class.xxx 的写法也会被替换成 [class xxx],所以只要在 class 中有声明一个名为 xxx 的方法,即可在代码中其它地方放心地写 class.xxx(这里暂时先不考虑把 class.xxx 写在等号左边被转换成调用 setter 方法的情况)

于是就变成了下面的样子

#import <Foundation/Foundation.h>

@interface Calculator : NSObject

@property (nonatomic,assign) int result;

- (Calculator *(^)(int))add;

- (Calculator *(^)(int))subtract;

- (Calculator *(^)(int))multiply;

- (Calculator *(^)(int))devide;

@end

通过阅读 Masonry 源码,我们可以发现它也是这么做的,只声明了方法,并没有声明相应的属性另外,对于 Masonry 链式语法中的 .and.with 等写法只是为了让代码读起来更通顺,实现方式为:声明定义一个名为 and 或 with 的方法,在方法里直接返回 self,如下:

- (MASConstraint *)with {
    return self;
}
- (MASConstraint *)and {
    return self;
}

以上,关于 Objective-C 链式语法的实现介绍完了

写的demo在此:
github
https://github.com/WooNoah/testLinkSyntax.git
百度云
https://pan.baidu.com/s/1ge8OnPh

参考资料:
http://www.ishuo.cn/doc/prhlafqf.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值