Masonry源码阅读笔记——使用Block实现链式编程

导语: 前段时间在阅读Masonry源码时,看到其内部使用了链式编程,比较有趣,这里简单分享一下;

在OC中实现链式编程并不难,最常用的实现是使用Block,具体包括以下几个要点:

1)对于要实现链式编程的函数,使用Block作为其返回值;

2)作为返回值的Block,需在执行后Return自身;

这里看起来似乎不太好理解,下面通过一个例子来说明:

@interface Box : NSObject

- (Box *(^)(CGFloat width))setWidth;
- (Box *(^)(CGFloat height))setHeight;
- (Box *(^)())setProperty;
- (Box *(^)())build;

@end

@implementation Box

- (Box *(^)(CGFloat width))setWidth {
    return ^(CGFloat width){
        NSLog(@"Set width : %f.", width);
        return self;
    };
}

- (Box *(^)(CGFloat height))setHeight {
    return ^(CGFloat height){
        NSLog(@"Set height : %f.", height);
        return self;
    };
}

- (Box *(^)())setProperty {
    return ^{
        NSLog(@"Set other property.");
        return self;
    };
}

- (Box *(^)())build {
    return ^{
        NSLog(@"A box is built.");
        return self;
    };
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Box *box = [Box new];
        box.setWidth(10.f).setHeight(10.f).setProperty().build();
    }
    return 0;
}

 在对象通过点语法调用函数时,返回了一个Block,在执行Block后,又返回了对象本身,这样就能将多个函数调用串联起来,实现链式的效果;

代码执行后为:

当然,链式编程很多时候并没有实际意义,例如上面的Demo,完全可以采用下面的实现:

@interface Box : NSObject

- (Box *)setWidth:(CGFloat)width;
- (Box *)setHeight:(CGFloat)height;
- (Box *)build;

@end

@implementation Box

- (Box *)setWidth:(CGFloat)width {
    NSLog(@"Set width : %f.", width);
    return self;
}

- (Box *)setHeight:(CGFloat)height {
    NSLog(@"Set height : %f.", height);
    return self;
}

- (Box *)build {
    NSLog(@"A box is built.");
    return self;
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Box *box = [Box new];
        [[[box setWidth:10.f] setHeight:10.f] build];
    }
    return 0;
}

但这样写一开始还能接受,链条一长时就会出现一堆恶心的中括号,这也是OC一直让人诟病的点;使用Block,形式上会美观许多;

当然,一般情况下还是不推荐链式编程的,因为这么写除了美观外毫无意义(个人愚见);但对于一些特殊的情况,例如使用Bulider模式,这么写可以使代码可读性更好,所以说,具体做法还是要视情况而定;

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据结构与算法

ABC108C - Triangular Relationship(打表)

给出$n, k$,求出满足$a+b, b + c, c + a$都是$k$的倍数的三元组$a, b, c$的个数,$1 \leqslant a, b, c \l...

1051
来自专栏xingoo, 一个梦想做发明家的程序员

在Java Web中使用Spark MLlib训练的模型

模型下载到本地,重新命名为xml。 可以看到默认四个特征分别叫做feild_0,field_1...目标为target

1242
来自专栏小樱的经验随笔

Lucas定理学习(进阶中)

(1)Lucas定理:p为素数,则有: ? ? ? (2)证明: n=(ak...a2,a1,a0)p = (ak...a2,a1)p*p + a0 =  [n...

2878
来自专栏MixLab科技+设计实验室

设计师编程指南之Sketch插件开发 8 之Cocoa基础知识

往期文章索引: 1 / 入门基本概念、page的相关操作 2 / artboard 、NSFileManager 和 NSString 关于文件及文件夹的相关操...

3098
来自专栏Java架构沉思录

什么是一致性哈希算法

原文:http://www.cnblogs.com/hapjin/p/4737207.html

1121
来自专栏进击的程序猿

seq2seq模型之raw_rnn

本文是seq2seq模型的第二篇,主要是通过raw_rnn来实现seq2seq模型。 github地址是:https://github.com/zhuanxu...

2152
来自专栏数据结构与算法

cf550D. Regular Bridge(构造)

一篇写的非常好的博客:http://www.cnblogs.com/mangoyang/p/9302269.html

681
来自专栏owent

POJ PKU 1986 Distance Queries 解题报告

题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1986

742
来自专栏专知

【附源码】TensorFlow动态图(Eager模式)的那些神坑

导读:TensorFlow的动态图(Eager模式)为TensorFlow提供了Pythonic的API,让开发者可以像使用PyTorch一样使用TensorF...

862
来自专栏生信宝典

R语言学习 - 线图绘制

线图 线图是反映趋势变化的一种方式,其输入数据一般也是一个矩阵。 单线图 假设有这么一个矩阵,第一列为转录起始位点及其上下游5 kb的区域,第二列为H3K27a...

1986

扫码关注云+社区