不知什么时候出现了一个叫“链式编程”的词,平时运用中在 Masonry 中使用的比较多,非常的清晰,自然。在百科中没有找到“链式编程”的定义,但是找到了“方法链”,目测应该是同一个东西。
定义
方法链(method chaining)是面向对象的编程语言中的一种常见语法,可以让开发者在只引用对象一次的情况下,对同一个对象进行多次方法调用。
优势
- 调用过程更接近自然语言
- 减少代码量
- 简化调用过程
缺点
- 不能在需要返回值中使用
Masonry 中方法链的运用
Masonry 中的使用方式:
源码:
// View+MASAdditions.h
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
self.translatesAutoresizingMaskIntoConstraints = NO;
MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
block(constraintMaker);
return [constraintMaker install];
}
// MASConstraintMaker.h
- (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;
}
// MASConstraint.h
- (MASConstraint * (^)(id attr))equalTo;
实例调用:
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(@(self.buttonSize.width));
make.height.equalTo(@(self.buttonSize.height));
}];
调用过程分析:
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block
mas_makeConstraints 返回的的是 NSArray 暂且不管,看他传入的参数为一个 Block ,输入参数为 MASConstraintMaker
block(constraintMaker); 将初始化的 constraintMaker 放入block中,既 make 为 constraintMaker,提供给 block 内部使用。并且执行block内部函数
return [constraintMaker install]; 完成布局配置
- (MASConstraint *)width {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth];
}
- (MASConstraint *)height {
return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight];
}
- (MASConstraint * (^)(id))equalTo {
return ^id(id attribute) {
return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
};
}
width、height、equalTo 返回的都是 MASConstraint,这样就形成了一个链式,可以通过 make.width.equalTo ,这种方式。其中 equalTo 为传入值返回 MASConstraint 的 block。
所以方法链,通过block调用,返回相同原型,形成的一种链式结构。
实现一个方法链
通过对方法链的定义,以及 Masonry 方法链使用的分析,尝试实现一个方法链。
功能:
实现个人信息录入
Person *p = [Person makeAddPeople:^(Person *make) {
make.changeName(@"张三").changeAge(11).changeAddress(@"地球");
}];
实现
step 1:
/// Person.h
+ (Person *)makeAddPeople:(void (^)(Person *make))block
{
Person *p = [[Person alloc] init];
block(p);
return p;
}
创建一个 makeAddPeople 方法,包含block,并且将 make 进行赋值,block内部操作将会使用make
step 2:
/// Person.h
- (Person *(^)(NSString *))changeName
{
return ^(NSString *nameValue){
self.name = nameValue;
return self;
};
}
添加 Person 信息时将返回 Person,作为后面原型链接,通过返回 block 的输入,用于外部调用传参,内部对make进行赋值
step 3:
Person *p = [Person makeAddPeople:^(Person *make) {
make.changeName(@"张三").changeAge(11).changeAddress(@"地球");
}];
NSLog(@"%@",p.name);
实现原来设计功能,能返回 ”张三“
网友评论