链式编程思想

链式编程是什么

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

    转自:http://www.cnblogs.com/chio/archive/2007/07/18/822389.html 首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 ...

  2. js发送post请求下载文件

    大家都知道ajax是不能直接下载文件的,所以一般都是通过一个超链接的形式去下载一个文件 但是当牵扯到需要发送很多数据到服务器上再下载的时候超链接的形式就有些太过勉强了 如下是一个工具方法(依赖jque ...

  3. ASP.NET性能监视参数详解

    性能监视器- Performance Monitor 性能监视器是Windows自带的系统资源和性能监视工具. 性能监视器能够量化地提供CPU使用率, 内存分配状况, 异常派发情况, 线程调度频率等信 ...

  4. spring MVC中文乱码相关总结

    总结几种方式,都使用的话能解决大多数乱码的情况 1.所有页面使用 <%@page language="java" pageEncoding="UTF-8" ...

  5. 【Tomcat】使用Eclipse运行Tomcat7源码

    1.搭建开发环境 a.下载好tomcat7源码包 b.安装好jdk7,及设置好环境变量 c.安装好ant,及设置好环境变量,用于预编译tocmat源码. d.以上步骤准备好我们就可以开始进入源码的预编 ...

  6. JavaSE复习日记 : 循环语句(for/while/do while)

    /* * 循环语句(for循环,while和do while循环) */ /* * for循环语句 * * for循环语法: * for (表达式1;表达式2;表达式3 ){ * java语句 * } ...

  7. 设计模式的PHP实现示例(转)

    symfony2 很多设计模式思想,下面的资料会有点帮助:http://www.open-open.com/lib/view/open1414996676559.html 阅读目录 Creationa ...

  8. 10min系列之二日志可视化进阶

    10min系列之二日志可视化进阶(作者原创,同步发布在github) 本文需要有一定的python和前端基础,如果没基础的,请关注我后续的基础教程系列博客 本文所有的demo,都是浏览器下展示的 原创 ...

  9. Page Cache, the Affair Between Memory and Files

    Previously we looked at how the kernel manages virtual memory for a user process, but files and I/O ...

  10. (iOS)viewController背景透明化

    #ifdef __IPHONE_8_0 ) { [UIApplication sharedApplication].keyWindow.rootViewController.providesPrese ...