链式编程思想

链式编程是什么

链式编程就是将调用多个方法用点语法连接起来,让代码更加简洁和可读性更高
刚开始接触链式编程是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. vb6.0 倒计时

    Dim t Dim start As Boolean Private Sub Command1_Click() If start = False Then t = Val(Text1) * 3600 ...

  2. Android 新兴的UI模式——侧边导航栏【转】

    侧边导航栏也就是大家熟知的SliddingMenu,英文也叫Fly-In App Menu.Side Navigation等.当然谷歌现在已经推出类似这个效果的组件--Navigation Drawe ...

  3. #pragma的用法

    在所有的预处理指令中,#Pragma   指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和 C++语言完全 ...

  4. Extjs 3.4 生成button,并調用相同的window

    /////定義一個方法,用來調用win_mucangjieshou的窗口 var panel_contant= function(id_name){ var aa=Ext.getCmp(id_name ...

  5. 解决 Tomcat reload WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [] registered the JDBC driver [com.mysql.jdbc.Driver] but fail

    转自:http://www.cnblogs.com/interdrp/p/5632529.html 我的错误如下: 06-Sep-2016 18:57:10.595 WARNING [localhos ...

  6. A Byte of Python 笔记(12)python 标准库:sys、os,更多内容

    第14章 python 标准库 Python标准库是随Python附带安装的,它包含大量极其有用的模块. sys 模块 sys 模块包含系统对应的功能.如 sys.argv 列表包含命令行参数. # ...

  7. Mysql的Debug模式实现

    前一段领导开发了一个内核的模块,测试的过程中,发现导致MYSQL客户端无法连接服务器. 经过查询文档,追根溯源,终于找到了MYSQL实现链接客户端的代码,在源文件sql-common/client.c ...

  8. HDU 1997 汉诺塔VII

    题解参考博客: http://blog.csdn.net/hjd_love_zzt/article/details/9897281 #include <cstdio> ],yes; int ...

  9. HDU 1722 Cake

    #include<cstdio> int gcd(int m, int n) { ?n:gcd(n % m, m); } int main() { int m, n; while(scan ...

  10. webscraping documentation — webscraping documentation

    webscraping documentation - webscraping documentation webscraping documentation¶ Introduction Backgr ...