masonry链式赋值的实现原理

2017-01-13 15:16:40来源:http://www.jianshu.com/p/70ed60c5c614作者:风___________人点击

[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.equalTo(self.view).sizeOffset(CGSizeMake(100, -50));
}];

- (MASConstraint *)size {
}

...............省略...................
NSMutableArray *children = [NSMutableArray arrayWithCapacity:attributes.count];
for (MASViewAttribute *a in attributes) {
//注意，children存储的MASViewConstraint实例对象
}
MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
constraint.delegate = self;
//注意，运行时返回的实际类型为MASCompositeConstraint
return constraint;
}

//.equalTo返回了一个block，定义为：MASConstraint * (^)(id)
- (MASConstraint * (^)(id))equalTo {
return ^id(id attribute) {
//注意，此处的self是MASCompositeConstraint的实例
return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
};
}

//size.equalTo(self.view) 实际上就是调用的MASCompositeConstraint的方法(MASCompositeConstraint.m实现)
- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
return ^id(id attr, NSLayoutRelation relation) {
for (MASConstraint *constraint in self.childConstraints.copy) {
//注意，constraint实际是MASViewConstraint实例变量
constraint.equalToWithRelation(attr, relation);
}
//注意,此处self依旧是MASCompositeConstraint
return self;
};
}

//MASViewConstraint中equalToWithRelation(attr, relation);的调用是调用了return的block;
- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
return ^id(id attribute, NSLayoutRelation relation) {
//attribute实际是self.view
if ([attribute isKindOfClass:NSArray.class]) {
} else {
//走的这里,到这里已经执行到终点了
return self;
}
};
}

//MASConstraint.m中
- (MASConstraint * (^)(CGSize))sizeOffset {
return ^id(CGSize offset) {
//注意，调用的MASCompositeConstraint的- (void)setOffset:(CGFloat)offset 方法
self.sizeOffset = offset;
return self;
};
}

//MASCompositeConstraint的- (void)setOffset:(CGFloat)offset 方法
- (void)setOffset:(CGFloat)offset {
for (MASConstraint *constraint in self.childConstraints) {
//调用的MASViewConstraint的- (void)setOffset:(CGFloat)offset 方法
constraint.offset = offset;
}
}

//MASViewConstraint的- (void)setOffset:(CGFloat)offset 方法
- (void)setOffset:(CGFloat)offset {
self.layoutConstant = offset;
}
//self.layoutConstant就是NSLayoutConstraint了添加约束，就不说啥了

---------------------------------分割线－－－－－－－－－－－－－

Masonry源码分析一
Masonry介绍与使用实践：快速上手Autolayout