OC中链式语法的使用及原理

最初见到链式语法的时候是在masonry库中,当时看到这种写法我是震惊的.一行代码可以赋值多个属性怎么一个爽字了得.一直没有去研究写法的实现.直到我看了一次公开课(为了避嫌,公开课的名字就不说了).在公开课中学到了链式语法的原理和写法.


原理

一般情况下 OC 的调用方法是这样的,比如 tableView 刷新数据的方法:

    [tableView reloadData];

当然我们也可以这样写:

    tableView.reloadData;

虽然 Xcode 会抛出一个警告,但是并不妨碍方法的执行.那么链式语法仅仅是这么做然后加了一个括号传递参数吗? 很显然不是.如果是有参数的方法我们这么做就会抛出错误.导致无法编译,就像这样:


QQ20170614-0.png

很遗憾,这种方法不对.如果可以这么做,相信很多讨厌 OC 调用方法方式的人都会开心吧.那么如何能让方法使用小括号接受参数呢?这里就需要借助 block 的语法了

block

还记得 block 怎么传递参数吗?是不是这样:

void(^block)(int i) = ^(int i){
     NSLog(@"%d",i);
};
block(1);

可以看到 block 使用小括号接受参数.如果一个方法返回值是一个 block 并且使用.语法调用在连接到一起是不是就成了这样:

方法实现:

// 返回一个接受一个 int 类型参数的 block
- (void(^)(int))test{
    
    void(^block)(int i) = ^(int i){
        NSLog(@"%d",i);
    };
    return block;
}

方法的正常调用步骤是这样的:

// 我们知道 self.test 就相当于 [self test] 
// 将 test 方法的返回值赋值给一个 block 变量 再使用变量调用 block 中的代码
void(^block)(int i) =self.test;
block(1);

如果连起来写就成了这样

// 因为 self.test 本身就返回了block 
//括号中的1看似是将值赋给了 test 方法,其实是赋给了 test 方法返回的 block
self.test(1);

不得不说大牛的脑洞大的可以.很巧妙的一个方法.初步实现了使用括号传递参数,接下来就要让他们组成链条

链接

有了上面的思路.再考虑让代码的调用形成链条就简单多了,只要让 block 返回 self 自身即可,就像这样:

// 当前类是ViewController类 block 返回 类对象 类对象是不是就可以继续调用 test 方法了
- (ViewController *(^)(int))test{
    
    ViewController *(^block)(int i) = ^ViewController *(int i){
        NSLog(@"%d",i);
        return self;
    };
    return block;
}

调用的时候就可以很爽的这么写了:

self.test(1).test(2).test(3);

看一下输出结果:

2017-06-14 23:40:04.268258+0800 链式语法[6727:1519931] 1
2017-06-14 23:40:04.268393+0800 链式语法[6727:1519931] 2
2017-06-14 23:40:04.268431+0800 链式语法[6727:1519931] 3

当然 masonry 中链式语法的使用更为复杂,这里只讲一下链式语法的书写原理.

链条的执行顺序

  1. self 调用 test 方法 test 方法返回 block
  2. block 得到小括号中的参数 并执行 block 中的代码
  3. block 返回对象 对象接着调用 test 方法 实际应用中 test 可以是任何这种格式的方法

关于block的一些小细节

  • block 是顺序执行的,并非异步执行,你觉得他是异步执行的很大一部分原因是因为大部分 block 是用来处理异步回调的
  • 书写时如果带返回值的 block 在实现的时候^的位置是在最左边,比如^ViewController *(int i)而不是像声明时一样返回值类型在最左边
  • block 的实现可以不写返回值类型 除非返回值类型是id并且返回值为nil的情况.这时必须在实现声明返回值类型是id,否则报错
id(^block)() = ^id(){
      // 返回 nil 必须在实现说明返回值类型是id
      return nil;
}
id(^block)() = ^(){
      // 返回 不为nil 可以不用声明返回值
      return slef;
}

Demo地址

https://github.com/JXnan/ChainTest

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容