masonry链式赋值的实现原理
2016-11-07 本文已影响221人
风___________
先定个小目标,比如先理解他一句话。。。。
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.equalTo(self.view).sizeOffset(CGSizeMake(100, -50));
}];
一: make.size//MASConstraintMaker中
- (MASConstraint *)size {
return [self addConstraintWithAttributes:MASAttributeWidth | MASAttributeHeight];
}
- (MASConstraint *)addConstraintWithAttributes:(MASAttribute)attrs {
...............省略...................
NSMutableArray *children = [NSMutableArray arrayWithCapacity:attributes.count];
for (MASViewAttribute *a in attributes) {
//注意,children存储的MASViewConstraint实例对象
[children addObject:[[MASViewConstraint alloc] initWithFirstViewAttribute:a]];
}
MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
constraint.delegate = self;
[self.constraints addObject:constraint];
//注意,运行时返回的实际类型为MASCompositeConstraint
return constraint;
}
二:size.equalTo(self.view)
//.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;
}
};
}
三:.sizeOffset(CGSizeMake(100, -50));
//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了添加约束,就不说啥了
运行时,各个类的穿插的也就上面理解的那样,其余的也大同小异
---------------------------------分割线-------------