第一篇:链式语法实现分析

引言

第三方自动布局框架 Masonry 的出现,是链式语法的鼻祖,也让我们见识到链式语法的魅力!

那么链式语法是如何实现的呢?下面将和大家一起学习。

如下是一段Masonry的布局代码:

[_countDownImg mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.mas_equalTo(kAutoLayoutWidth(-12.f));
    make.centerY.mas_equalTo(self.view.mas_centerY).with.offset(20);
            make.width.mas_equalTo(kAutoLayoutWidth(174.f));
}];

我们关注的语法点其实是

make.right.mas_equalTo(kAutoLayoutWidth(-12.f));
make.centerY.mas_equalTo(self.view.mas_centerY).with.offset(20);
make.width.mas_equalTo(kAutoLayoutWidth(174.f));

这句代码中的多个点链式语法

一、make

make 是一个类 MASConstraintMaker创建的对象,MASConstraint 继承 NSObject

二、right、top、bottom、width

right、top、bottom、width 均为make对象的公开属性,属于MASConstraint 类。

right为例,其基本写法为

@interface MASConstraintMaker : NSObject

@property (nonatomic, strong, readonly) MASConstraint *left;

@end

具体实现

- (MASConstraint *)left {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
}

三、mas_equalTo这个是重点,也是核心所在

这个是mas_equalTo的实现代码

.h中 这里是方法,直接可以用.式语法实现

扫描二维码关注公众号,回复: 5205937 查看本文章
- (MASConstraint * (^)(id attr))mas_equalTo;

.m中具体实现

- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
    return ^id(id attribute, NSLayoutRelation relation) {
        if ([attribute isKindOfClass:NSArray.class]) {
            NSAssert(!self.hasLayoutRelation, @"Redefinition of constraint relation");
            NSMutableArray *children = NSMutableArray.new;
            for (id attr in attribute) {
                MASViewConstraint *viewConstraint = [self copy];
                viewConstraint.layoutRelation = relation;
                viewConstraint.secondViewAttribute = attr;
                [children addObject:viewConstraint];
            }
            MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children];
            compositeConstraint.delegate = self.delegate;
            [self.delegate constraint:self shouldBeReplacedWithConstraint:compositeConstraint];
            return compositeConstraint;
        } else {
            NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSValue.class], @"Redefinition of constraint relation");
            self.layoutRelation = relation;
            self.secondViewAttribute = attribute;
            return self;
        }
    };
}

从这个逻辑来看,这里是利用了一个 <u>block</u> 来实现这个代码和链式语法

这个block 有两个核心特点

  • 带返回值 MASConstraint ,返回值就为这个对象本身,这样每次返回值可以继续用其对象属性
  • 带入参 id, NSLayoutRelation,边界条件、具体约束的值和约束对象。

链式语法的实现总结

不带入参

  • 一、创建一个属性,这个属性属于你需要的类,重写其get方法。
.h文件
@property (nonatomic, strong, readonly) MASConstraint *left;
.m文件
- (MASConstraint *)left {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
}

  • 二、写一个公开方法,返回值为目标类的对象,并实现其方法
.h文件
- (MASConstraint *)left;
.m文件
- (MASConstraint *)left {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
}

带入参

  • 只需要将这个创建一个带返回值和入参的Block即可,可以是属性,也可以是方法。

- (MASConstraint * (^)(id attr))mas_equalTo;


- (MASConstraint * (^)(id))mas_equalTo {
    return ^id(id attribute) {
        return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
    };
}


如下是链式语法相关博客
第一篇:链式语法实现分析
第二篇:链式语法使用实战

猜你喜欢

转载自blog.csdn.net/weixin_34417200/article/details/86867903