链式编程思想

链式编程是什么

链式编程就是将调用多个方法用点语法连接起来,让代码更加简洁和可读性更高
刚开始接触链式编程是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. o怎么样racle输入dmp数据库文件

    Oracle进出口数据imp/exp等价物oracle数据恢复和备份. exp命令可以从远程数据库传输数据server出到本地的dmp文件,imp命令能够把dmp文件从本地导入到远处的数据库serve ...

  2. C# 关于数据类型转换

    1.强制转换; 需要注意的一个是char不能强制转化成int,如果使用强制转化,得到的是原整数的ASCII码值.该方式对于浮点数会做无条件舍去,失去精确度. 2.利用方法: 类型.Parse(stri ...

  3. Java RMI 简介及其优劣势总结

    今天,帮别人看UDAS配置问题时,看到采用的是RMI方式的调用,如:rmi://10.20.134.140:2299/DataServer,而且这个端口是被直接硬编码在UDAS的代码中的.既然看到了, ...

  4. Hibernate与iBATIS的比较

    1.出身 hibernate 是当前最流行的o/r mapping框架,它出身于sf.net,现在已经成为jboss的一部分了. ibatis 是另外一种优秀的o/r mapping框架,目前属于ap ...

  5. ##DAY2 UILabel、UITextField、UIButton、UIImageView、UISlider

    ##DAY2 UILabel.UITextField.UIButton.UIImageView.UISlider #pragma mark ———————UILabel——————————— UILa ...

  6. C/C++中字符串的输入问题

    standard C I/O 头文件:#include <stdio.h> . getchar() 原型:int getchar(void); 功能:从标准输入获取并返回下一个字符,并释放 ...

  7. 网页往数据库里插数据要用utf8,否则就乱码

    把网页的这行<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> ...

  8. codeforces 626E. Simple Skewness 三分

    题目链接 给n个数, 让你去掉一些数, 使得剩下的数的平均值-中位数的差值最大. 先将数组排序, 然后枚举每一个数作为中位数的情况, 对于每个枚举的数, 三分它的左右区间长度找到一个平均值最大的情况, ...

  9. [LeetCode]题解(python):084-Largest Rectangle in Histogram

    题目来源: https://leetcode.com/problems/largest-rectangle-in-histogram/ 题意分析: 给定一个数组,数组的数字代表这个位置上的bar的高度 ...

  10. C语言(1)--准备

    经过很长一段时间的准备,终于重新弄懂了一些C语言的问题,再次熟悉了C语言的大致应用,对此略有体会,在此以博客记录于此! 准备工作: 运行平台:Linux 编辑工具:vim (还可以使用emac,ged ...