内容简介:编程思想在实际上是遍历了我们创建约束制造者
编程思想在 iOS
的应用中大概有那么几类,我们最常用的当属于面向对象的编程思想,一切皆对象,基于这种思想离不开的就是我们最常用的封装、继承、多态。平时工作中我们也会接触一些面向协议的编程思想,比如说接口分离解耦合,再比如说我们最常用的 delegate
都是面向协议的思想,还有就是基于 ReactiveCocoa
框架也就是平时听到的RAC提供的响应式编程思想,今天主要分析下另一种编程思想,链式编程。
首先简单分析一下Masonry的实现过程:
Masonry
框架作为 iOS
开发者耳熟能详,大家在做纯代码适配的时候应该都曾用过,下面就以 Masonry
为例,但本文不过多的分析 MAS
源码,旨在提炼思想。
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block { self.translatesAutoresizingMaskIntoConstraints = NO; MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self]; block(constraintMaker); return [constraintMaker install]; } - (id)initWithView:(MAS_VIEW *)view { self = [super init]; if (!self) return nil; self.view = view; self.constraints = NSMutableArray.new; return self; } 复制代码
-
1.创建约束制造者
MASConstraintMaker
并且绑定控件,在约束制造者init
的同时生成了一个保存所有约束的数组constraints
。 -
2.执行
mas_makeConstraints
传入的block
,返回我们刚才创建的约束制造者constraintMaker
。 -
3.让约束制造者安装约束,执行
install
方法。
我们再看一下install里面做了什么:
- (NSArray *)install { if (self.removeExisting) { NSArray *installedConstraints = [MASViewConstraint installedConstraintsForView:self.view]; for (MASConstraint *constraint in installedConstraints) { [constraint uninstall]; } } NSArray *constraints = self.constraints.copy; for (MASConstraint *constraint in constraints) { constraint.updateExisting = self.updateExisting; [constraint install]; } [self.constraints removeAllObjects]; return constraints; } 复制代码
实际上是遍历了我们创建约束制造者 constraintMaker
时所创建的 constraints
, constraints
里面实际上存储的是我们为控件添加的所有约束信息,然后分别对每条约束之行 install
。那么问题来了, constraints
里面的约束从哪里来的呢。这就要回到了上面说的第 2
步, block
将约束制造者返回给用户,让用户通过 constraintMaker
去设置控件的约束,这些约束实际上就是存储到了 constraints
中。当执行第 3
步 return [constraintMaker install];
的时候,就是将所有调用者添加的布局转换为 NSLayoutConstraint
对象也就是我们熟悉的纯代码适配,进行布局更新。
为什么要先研究Masonry呢
实际上 Masonry
就是基于链式编程思想实现的开源框架,即强大,又直观。比如说我们在使用 Masonry
的时候通常会这样写:
[view mas_makeConstraints:^(MASConstraintMaker *make) { make.height.top.mas_equalTo(44); make.left.mas_equalTo(5); make.centerY.equalTo(self); }]; 复制代码
为什么 make
可以一直这么点下去,点语法给我们的第一感觉是 get
方法,实际上确实是 get
方法:
- (MASConstraint *)height { return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight]; } 复制代码
通过源码可以看到 .height
实际上返回的并不是一个 int
或者 NSInteger
类型变量,而是 MASConstraint
,是约束制造者本身,实际上每次调用.height就是将约束添加到我们上面提到的constraints数组中。到这里,链式编程的特点就显而易见了, 那就是方法返回值必须要有方法的调用者
。那么还有疑问, mas_equalTo()
是什么鬼。下面着重讲一下 .mas_equalTo()
,
还是通过源代码点进去看一下:
- (MASConstraint * (^)(id))equalTo { return ^id(id attribute) { return self.equalToWithRelation(attribute, NSLayoutRelationEqual); }; } 复制代码
返回值是一个 MASConstraint * (^)(id)
的 block
类型,到这里我们了解了 .mas_equalTo
实际上是返回了一个返回值为 MASConstraint
类型的 block
,当我们外面调用 block
的时候实际上执行的是 self.equalToWithRelation(attribute,NSLayoutRelationEqual);
函数,没错,它返回的依旧是 MASConstraint
类型,依旧是方法的调用者,也就是前面提到的约束制造者,所以我们在调用 mas_equalTo()
之后还能继续点下去,像不像个无底洞。如果这样不好理解的话我们可以将添加约束的源码改写一下来实现:
[view mas_makeConstraints:^(MASConstraintMaker *make) { // make.height.top.mas_equalTo(44); MASConstraint * (^)(id)block = make.height.top.mas_equlTo; MASConstraint *make = block(44); make.top... }]; 复制代码
这下应该就很好理解了。
最后总结一下什么是链式编程,一句话就是方法返回值必须要有方法的调用者!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 浅析阿里分布式事务组件 fescar 2pc 的设计思想
- 常用算法思想之动态规划的后缀思想
- 常用算法思想之动态规划的区间子集思想
- Linux 背后的思想
- 深入简出-- iOS编程思想
- 前端架构思想:聚类分层
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Probabilistic Method Second Edition
Noga Alon、Joel H. Spencer / Wiley-Blackwell / 2000 / $121.95
The leading reference on probabilistic methods in combinatorics-now expanded and updated When it was first published in 1991, The Probabilistic Method became instantly the standard reference on one......一起来看看 《The Probabilistic Method Second Edition》 这本书的介绍吧!