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

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

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

编程思想在 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...
}];
复制代码

这下应该就很好理解了。

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


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

查看所有标签

猜你喜欢:

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

Making Things See

Making Things See

Greg Borenstein / Make / 2012-2-3 / USD 39.99

Welcome to the Vision Revolution. With Microsoft's Kinect leading the way, you can now use 3D computer vision technology to build digital 3D models of people and objects that you can manipulate with g......一起来看看 《Making Things See》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

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

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具