链式编程思想

链式编程是什么

链式编程就是将调用多个方法用点语法连接起来,让代码更加简洁和可读性更高
刚开始接触链式编程是Masonry,用起来真的非常爽

1
make.left.right.top.equalTo(self.view);

这样一句语句就调用了4个方法
.left调用了left属性的get方法
.right, .top调用了right和top方法
.equalTo()调用了equalTo方法

这种写法极大简化了写约束的方式

原理

原理就是调用的属性的类型或者方法的返回类型为原调用属性的类型
例如说UILabel调用了某个方法或者属性,得到的类型还是UILabel,那么还可以继续调用UILabel的属性或者方法

如何实现

看了Masonry,我发现有两种实现方式

1.用点语法调用方法

这个其实我之前没发现,写习惯了用方括号调用方法
例如创建一个label 可以这样写UILabel *label = [[UILabel alloc] init
其实也可以这样写UILabel *label = UILabel.alloc.init
不过后种方法几乎没人用,苹果应该也不推荐这种写法,因为有时候这样写是没有代码提示的
但是有一个缺点就是不能调用有参数的方法,所以我们只能写没有参数的方法

创建一个UIButton的分类
写两个方法

1
2
- (UIButton *)setTextHello;
- (UIButton *)setTextColorRed;

并且实现

1
2
3
4
5
6
7
8
9
10
11
- (UIButton *)setTextColorRed
{
[self setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
return self;
} - (UIButton *)setImage
{
[self setImage:[UIImage imageNamed:@"Stan1"] forState:UIControlStateNormal];
return self;
}

然后我们创建一个按钮的时候就可以这样写

1
2
3
4
5
//创建一个按钮
UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoLight];
button.frame = CGRectMake(100, 100, 100, 100);
button.setTextHello.setTextColorRed;
[self.view addSubview:button];

效果如图

但是会报一个警告,因为调用的是属性,但是这个属性没有被用到
解决方法是在调用属性前面加(void),这样就可以了

2.用属性调用

新创建一个UILabel的分类
如果要传入参数的话,就返回一个UILabel的block,可以在block里面实现你想要实现的东西

1
2
3
@property(nonatomic,copy) UILabel* (^kText)(NSString *text);
@property(nonatomic,copy) UILabel* (^kFont)(NSUInteger fontSize);
@property(nonatomic,copy) UILabel* (^kTextColor)(UIColor *color);

加k是为了易于区分,可以不加的
因为这是在分类里面的属性,不会生成setter和getter方法,所以都要自己写
实现如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- (UILabel *(^)(NSUInteger))kFont
{
return ^(NSUInteger font){
[self setFont:[UIFont systemFontOfSize:font]];
return self;
};
} - (UILabel *(^)(NSString *))kText
{
return ^(NSString *text){
[self setText:text];
return self;
};
} - (UILabel *(^)(UIColor *))kTextColor
{
return ^(UIColor *color){
[self setTextColor:color];
return self;
};
} - (void)setKFont:(UILabel *(^)(NSUInteger))kFont{}
- (void)setKText:(UILabel *(^)(NSString *))kText{}
- (void)setKTextColor:(UILabel *(^)(UIColor *))kTextColor{}

不会用到setter方法,也不能用,所以setter方法设为空
然后就能愉快的链式编程了

然后我再想,假如没有参数呢,刚开始是想block没有参数

1
2
3
@property(nonatomic,copy) UILabel* (^aText)();
@property(nonatomic,copy) UILabel* (^aFont)();
@property(nonatomic,copy) UILabel* (^aTextColor)();

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- (UILabel *(^)())aFont
{
return ^(){
[self setFont:[UIFont systemFontOfSize:16.0f]];
return self;
};
} - (UILabel *(^)())aTextColor
{
return ^(){
[self setTextColor:[UIColor cyanColor]];
return self;
};
} - (UILabel *(^)())aText
{
return ^(){
[self setText:@"这还是一个label"];
return self;
};
} - (void)setAFont:(UILabel *(^)())aFont{}
- (void)setAText:(UILabel *(^)())aText{}
- (void)setATextColor:(UILabel *(^)())aTextColor{}

后来发现调用的时候还是要这样

尝试了一下,最后一个调用能去掉括号,报警告,能运行,但是没效果

所以我想为什么不直接调用属性

1
2
3
@property(nonatomic,strong) UILabel *bText;
@property(nonatomic,strong) UILabel *bFont;
@property(nonatomic,strong) UILabel *bTextColor;

getter && setter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- (UILabel *)bText
{
[self setText:@"labellabel"];
return self;
} - (UILabel *)bTextColor
{
[self setTextColor:[UIColor purpleColor]];
return self;
} - (UILabel *)bFont
{
[self setFont:[UIFont systemFontOfSize:13.0f]];
return self;
} - (void)setBFont:(UILabel *)bFont{}
- (void)setBText:(UILabel *)bText{}
- (void)setBTextColor:(UILabel *)bTextColor{}

调用

1
2
3
UILabel *label3 = [[UILabel alloc] initWithFrame:CGRectMake(100, 400, 200, 100)];
(void)label3.bTextColor.bText.bFont;
[self.view addSubview:label3];

如果调用不加(void)还是会报警告
如果想像Masonry那样的链式编程可以这样写

1
2
3
UILabel *label3 = [[UILabel alloc] initWithFrame:CGRectMake(100, 400, 200, 100)];
label3.bTextColor.bText.kFont(30);
[self.view addSubview:label3];

这样就不会报警告,整洁清晰

还发表在 我的个人博客

Objective-C 链式编程思想的更多相关文章

  1. iOS 开发之使用链式编程思想实现简单的计算器

    链式编程思想是将多个操作(多行代码)通过点号(.)链接在一起成为一句代码,使代码可读性好.例如 a(1).b(2).c(3). 链式编程思想最为关键的是,方法的返回值是block,block必须返回对 ...

  2. 模仿Masonry链式编程思想

    使用masonry 也将近一年多了,它的链式编程方式一直是很吸引我的. 之前一直没空好好思考它是如何实现,直到现在正好自己有空,因此写下链式编程的基本思路. 链式基本的编程形式如 a.property ...

  3. ASP.NET MVC学前篇之扩展方法、链式编程

    ASP.NET MVC学前篇之扩展方法.链式编程 前言 目的没有别的,就是介绍几点在ASP.NETMVC 用到C#语言特性,还有一些其他琐碎的知识点,强行的划分一个范围的话,只能说都跟MVC有关,有的 ...

  4. ios的链式编程笔记

    1.Masonry的语法为啥能连续的使用点语法? >> 底层使用的是:用block当函数的返回参数  > 链式编程思想 2. 使用block当函数的返回参数 // 之前开发中比较习惯 ...

  5. 由表单验证说起,关于在C#中尝试链式编程的实践

    在web开发中必不可少的会遇到表单验证的问题,为避免数据在写入到数据库时出现异常,一般比较安全的做法是前端会先做一次验证,通过后把数据提交到后端再验证一次,因为仅仅靠前端验证是不安全的,有太多的htt ...

  6. iOS 链式编程探索(Masonry)

    看了几篇关于链式编程的文章,还是理解的不透彻,我想这可能是因为我自己对block掌握的不熟练. 我已经明白了,所以,和大家分享一下我的理解!如有问题,麻烦大家指出! 直接看代码吧!关键的注释都有. 我 ...

  7. 原生JS实现jquery的链式编程。

    这是我根据之前遇到的一个面试题,题目:用原生JS实现$("#ct").on("click",fn).attr("id"). 然后看了篇jqu ...

  8. Java链式编程接口

    在android开发中显示一个AlertDialog时,常采用下列的写法: new AlertDialog.Builder(getApplicationContext()) .setTitle(&qu ...

  9. JavaScript系列:模块化与链式编程

    模块化:闭包和和函数作用域(JS没有块级作用域ES6之前)构造模块 var man=function(){ var age=12; return { getYear:function(){ retur ...

随机推荐

  1. 合作开发,导入MyEclipse项目报错问题

    因工作原因,同事将他的java项目交接给了我.和平时的交接一样.他把他最新的源代码,打成压缩包,发给我.我解压后,使用myeclipse开发工具,通过导入,将项目导入到我的开发工具中,这个时候有一个问 ...

  2. Android开发之布局优化

    1.抽象布局标签 (1) <include>标签 include标签经常使用于将布局中的公共部分提取出来供其它layout共用,以实现布局模块化.这在布局编写方便提供了大大的便利. 以下以 ...

  3. 2014年辛星Javascript解读第二节

    本小节我们解说一下Javascript的语法,尽管js语言很easy,它的语法也相对好学一些,可是不学总之还是不会的,因此,我们来一探到底把. ********凝视************* 1.我们 ...

  4. jQuery 插件 flexslider 初步使用

    发现了个不错的 jQuery 幻灯片插件 flexslider,有 接近 3000 Star,应该说是很靠谱的,下面是简单使用教程. 引入代码 所有代码都可以在 flexlslider 的 Githu ...

  5. 简单天气应用开发——解析HeWeather JSON

    借助和风天气API成功获取到了我想要的天气信息,但在怎么提取出我想要的数据上又遇到了问题. {"HeWeather data service 3.0":[{"basic& ...

  6. Windows 配置JAVA的环境变量

    Java是由Sun公司开发的一种应用于分布式网络环境的程序设计语言,Java语言拥有跨平台的特性,它编译的程序能够运行在多种操作系统平台上,可以实现“一次编写,到处运行”的强大功能. 工具/原料 JD ...

  7. 获取执行计划——EXPLAN PLAN

    一般获取执行计划有四种途径:1.执行explain plan,查询结果输出表.2.查询动态性能视图,它显示缓存在库缓存中的执行计划(有时查不出结果是因为执行计划已经不在库缓存中).3.查询AWR或St ...

  8. 织梦dedecms|文章页通用标签

    当前位置: {dede:field name='position'/}上一页: {dede:prenext get='pre'/}下一页:    {dede:prenext get='next'/}收 ...

  9. selenium 学习笔记 ---新手学习记录(2) 问题总结

    今天研究了下ie.chrome.firefox浏览器执行脚本 1.首先firefox下执行时,我是安装在d盘了,所以要更改路径 //如果火狐浏览器没有默认安装在C盘,需要制定其路径 System.se ...

  10. Correlation rule tuning

    Lots of organizations are deploying SIEM systems either to do their due diligence or because it’s pa ...