OC Block高级用法——链式编程简谈
关于“链式编程”网上也有这方面的文章,这里就简单地谈一下个人的一点愚见,抛砖引玉吧,有不对的地方还请各位看官指正。
先看段代码
UIBtn(@"btn1").frame_l(CGRectMake(100, 100, 100, 60))
.backgroundColor_l([UIColor redColor])
.action(self, @selector(action1:), UIControlEventTouchUpInside)
.addToView(self.view);
上面这句代码,将多行代码通过.
链接成一句代码,这就是链式编程,也是链式编程的一个优点特点。使用起来很简洁,可读性好。
怎么才能实现这样的效果呢?看到.
我想很多人会想到点语法
,在oc里我们首先会想到一个类的实例对象的属性
可以被点出来。那么我们怎么才能够一直点下去呢?那就是不断地返回这个实例对象。继续往下想,什么有返回值呢?方法有返回值,但是绝大多数的方法不能用.
调用啊,WTF!怎么办。是的,还有Block啊,而且Block还可以声明成类的属性。
分析到这,那么我们就有了一个基本的思路:在类里的属性用Block,而且Block的返回值是该类的一个实例,然后在这个Block里我们去做一些相应的操作。
下面我以UIButton
为例简单说一下。首先我们创建一个UIButton的Category,当然用继承也可以。也许有的小伙伴找不到创建的地方,上个图。之后的应该都会了。
接下来上代码(一块来吧,我觉得这样直观一些,后面再分开说),先来.h
#import <UIKit/UIKit.h>
@interface UIButton (Link)
@property (nonatomic, copy) UIButton *(^frame_l)(CGRect rect);
@property (nonatomic, copy) UIButton *(^backgroundColor_l)(UIColor *color);
@property (nonatomic, copy) UIButton *(^addToView)(UIView *view);
@property (nonatomic, copy) UIButton *(^action)(id target, SEL selector, UIControlEvents events);
UIButton * UIBtn(id name);
@end
- 这里声明了四个Block,分别用来设置frame,backgroundColor,要添加到的父视图,以及Action点击事件
下面的c方法,是用来创建实例对象的,里面的参数相当于对象名,就不用这样
[UIButton buttonWithType:UIButtonTypeCustom];
创建了,写起来更整洁再来
.m
#import "UIButton+Link.h" UIButton *button; @implementation UIButton (Link) -(UIButton *(^)(CGRect))frame_l { return ^(CGRect fra) { button.frame = fra; return button; }; } -(void)setFrame_l:(UIButton *(^)(CGRect))frame_l {}; -(UIButton *(^)(UIColor *))backgroundColor_l { return ^(UIColor *color) { button.backgroundColor = color; return button; }; } -(void)setBackgroundColor_l:(UIButton *(^)(UIColor *))backgroundColor_l {}; -(UIButton *(^)(UIView *))addToView { return ^(UIView *view) { [view addSubview:button]; return button; }; } -(void)setAddToView:(UIButton *(^)(UIView *))addToView {}; -(UIButton *(^)(id, SEL, UIControlEvents))action { return ^(id target, SEL selector, UIControlEvents events) { [button addTarget:target action:selector forControlEvents:events]; return button; }; } -(void)setAction:(UIButton *(^)(id, SEL, UIControlEvents))action {}; @end UIButton * UIBtn(id name) { button = [UIButton buttonWithType:UIButtonTypeCustom]; return button; }
.m
主要就是实现属性的getter和setter方法,这里实现setter是为了消除警告- c方法中我们对全局的button对象初始化,然后每个属性的getter方法都返回这个对象
这样我们在使用时,就达到了文章开头那段代码的效果,实现了“链式编程”。可以一直点点点了
但是现在Xcode对Block的提示不是太友好
当我们按下回车之后,只会出现addToView
不会自动补齐后面的参数
就说这么多吧,有兴趣的童鞋可以继续添加属性设置。
最后来个彩蛋,关于Block
在调用Block时我们都会先判断其是否为nil,防止崩溃,通常是这样的
if (block) { block(); }
其实还可以这样
!block ? : block();
时间仓促,文章有误之处还请各位留言指正。技术无止境,共同进步,写出优雅的代码,是我不变的追求。
本文系作者 @一懒众衫小 原创发布在一懒众衫小站点。未经许可,禁止转载。
暂无评论数据