因为有 Masory 以及 Snapkit 这些知名开源库的存在,相信很多 iOS 开发者对链式编程都不会太陌生,先来看下面这句代码:
|
|
这句代码就属于链式编程,而且 Masonry 框架本身也是通过链式语法对 NSLayoutConstraints 进行的封装。对 Masonry 感兴趣的童鞋可以读读这篇文章 iOS开发之源码解析 - Masonry。
链式编程思想:
所谓链式编程就是通过点(.)将多个操作链接在一起成为一句代码,使代码更加紧凑,也提高了代码的可读性(如上面那句代码)。
链式编程特点:
- 方法的返回值是 block,block 中必须有一个返回值,通常返回它本身,也可以是处理后的数据或对象。
- 返回值中的 block 具备两个功能,第一:可以作为类的属性被’点’出来。第二:可以当作函数直接调用。
- 通常会通过调用一个函数来给属性赋值,在函数内部封装赋值的语句,也可以加入一些判断逻辑等。
链式编程练习
我这里写了一个 UILabel 的扩展类用来练习链式编程,叫做 UILabel+NNCategory
。利用这个分类创建 UILabel,并为其设置frame,text,font,textColor,backgroundColor
等属性,代码如下:
|
|
细心观察上面的代码,我们可以猜出 nn_frame()
,nn_text()
,nn_fontSize()
这些都是属性,不过为什么它们后面都带有括号呢?这是因为这些属性都是 block
类型。那么为什么它们可以点出来呢?即为什么可以 label.nn_frame().nn_text().nn_fontSize()
这么用?简单来说,就是因为这些 block
类型的属性都带有返回值!
下面是分类 UILabel+NNCategory
的详细实现过程
- 在 UILabel+NNCategory.h 中声明一些属性
|
|
我们在 UILabel 分类里面声明了这些属性,所以接下来只要是 UILabel 类型都可以点出来这些属性。这里也可以看出这些属性都是 block
类型。我们抽出一句代码简单说明一下:@property (nonatomic, copy, readonly) UILabel *(^nn_text)(NSString *);
,这句代码声明了一个 block(^) 原型,名字叫做 nn_text,包含了一个 NSString 类型的参数,返回值是 UILabel 类型。
- 在 UILabel+NNCategory.m 中实现
|
|
UILabel+NNCategory.m
中的这些是 UILabel+NNCategory.h
文件中属性的 getter 方法。我们抽出一个简单说明一下
|
|
这个属性的类型是 block,具体是 UILabel *(^nn_text)(NSString *)
类型,需要说明的是,我们用 block 并不是为了返回 block 对象本身,而是为了在 block 内部执行一些操作,所以我们在属性的 getter 方法中首先返回一个临时的 block 对象,主要是为了在 block 内部返回 UILabel 类型的对象。具体请看上面代码块中的一些注释。
这时我们还需要定义一个方法方便外界调用,这个方法主要有两个功能,第一是用来创建 UILabel ,第二是为其“点”出各种属性。
- 在 UILabel+NNCategory.h 中声明一个方法
|
|
这里是模仿 Masonry,我们通常用 Masonry 加约束时首先会调用这个方法:- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block
,
|
|
我们用 Masonry 加约束时调用这个方法,是因为 Masonry 在这个方法内部早已做好一些所需要的操作。所以接下来我们也要在 UILabel+NNCategory.m 中做些事情。
- 在 UILabel+NNCategory.m 中实现这个方法
|
|
上面这个方法首先初始化一个 UILabel 对象,接着把 UILabel 添加到传过来的 superView 上,然后对 block 进行回调,执行 block,把外界对 UILabel 设置的属性添加上去,最后返回 UILabel 对象。
这就是一些简单的链式编程思维,外界调用的时候只需如下代码即可:
|
|
效果图如下: