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));
}];

一: 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了添加约束,就不说啥了

运行时,各个类的穿插的也就上面理解的那样,其余的也大同小异

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


链式赋值的实现原理:block的回调获取参数内部使用,所有的set方法返回MASConstraint实例,可以通过'.语法'继续访问
看的略糙~下面几个比较详细,等有时间了仔细看看

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




最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台