简介
相信大部分ios开发人员都使用过Masonry(强大约束封装框架),对它的make.left.equalTo()或者make.left.equalTo().and.right.equalTo()应该有很深刻的印象吧,这种编程方式就叫链式编程。从它的语法可以看出它的任务方法是一步步的“点”出来,然后执行,可读性和操作性都很高,那么这是怎么实现的?
分析与实现
先来看看它的“点”语法:在ios中,“点”语法很常见,比如我要创建一个label,并设置一些属性:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(100, 300, 60, 30)];
label.text = @"";
label.font = [UIFont systemFontOfSize:16];
label.textColor = [UIColor redColor];
[self.view addSubview:label];
创建好后,感觉每次都要用label对象“点”属性出来设置,有点麻烦。那可不可以像Masonry那样,一个对象,直接“点”一连窜任务出来实现,是不是就要方便一些。比如像下面这样:
label.text(@"喔喔喔").textFont([UIFont fontOfSize:16]).textColor([UIColor redColor]);
有Masonry在前,不用想太多,那肯定是可以实现的,现在就来看看如何一步步实现吧。
都知道,对象“点”属性(如:label.text),既然对象才能调出属性,那我们在设置text的方法中携带一个该对象,是不是就能继续往下调用。现在我重新声明一个text方法,让其携带一个label对象(实现文件为UILabel的类别文件):
- (UILabel *(^)(NSString *text))cp_text;
加个前缀cp是为了区分系统的text方法
该方法的返回值是一个block,block内又返回了一个UILabel对象,^表示这是一个代码块,NSString *text这是传入的参数。再来看看实现:
- (UILabel *(^)(NSString *text))cp_text
{
return ^(NSString *text)
{
self.text = text;
return self;
};
}
整体返回了一个block,block内部执行的逻辑就是对label.text的赋值和返回该对象,返回对象就是用于连续调用其他类似的方法。按照这种思路,再来实现UILabel的其他几个方法:
- (UILabel *(^)(UIColor *color))cp_textColor
{
return ^(UIColor *color)
{
self.textColor = color;
return self;
};
}
- (UILabel *(^)(UIFont *font))cp_textFont
{
return ^(UIFont *font)
{
self.font = font;
return self;
};
}
现在来看看连续调用:
UILabel *label = UILabel.cp_init.cp_frame(100,300,60,30);
label.cp_text(@"喔喔喔").cp_textFont(SFONT(16)).cp_textColor(RedColor);
self.view.cp_addSubView(label);
为了语法统一,我对其初始化方法也封装了一次,使其整体看起来比较连贯,流畅。
总结
链式编程在ios oc中使用频率并不高,不过在其环环相扣的语法上来看,某些时候调用起来确实很方便。我写了个demo,封装了UIView,UILabel,UIButton的一些属性和方法,感兴趣的可以去我的项目地址下载下来看看。
git项目地址