浅析iOS-MAS&链式编程思想

栏目: IOS · 发布时间: 6年前

内容简介:编程思想在实际上是遍历了我们创建约束制造者

编程思想在 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 时所创建的 constraintsconstraints 里面实际上存储的是我们为控件添加的所有约束信息,然后分别对每条约束之行 install 。那么问题来了, constraints 里面的约束从哪里来的呢。这就要回到了上面说的第 2 步, block 将约束制造者返回给用户,让用户通过 constraintMaker 去设置控件的约束,这些约束实际上就是存储到了 constraints 中。当执行第 3return [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...
}];
复制代码

这下应该就很好理解了。

最后总结一下什么是链式编程,一句话就是方法返回值必须要有方法的调用者!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JAVASCRIPT语言精髓与编程实践

JAVASCRIPT语言精髓与编程实践

周爱民 / 电子工业出版社 / 2008-3 / 68.00元

《JAVASCRIPT语言精髓与编程实践》讲述了JavaScript的语言实现与扩展,主要包括以下三个方面的内容:(1)动态、函数式语言,以及其它语言特性在JavaScript的表现与应用;(2)如何用动态函数式语言的特性来扩展JavaScript的语言特性与框架;(3)如何将JavaScript引擎整合到其它高级语言的开发过程中。一起来看看 《JAVASCRIPT语言精髓与编程实践》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具