随着学习的深入,对block的认识也是越来越清晰,就是”一个可以截获自动变量的匿名函数“,在一般应用上比较顺手,但是在底层的转化上面还在学习中,这里不涉及,只是如标题写的应用方面的写法及中间遇到的问题。
我们先说一下block的回调
现在有这样一个需求,一个人(称为A)想剪发,让理发师(称为B)帮助他剪发,剪发过程B决定。
A.h文件
#import <Foundation/Foundation.h>
@interface PeopleA : NSObject
-(void)doSometing:(void(^)())someOne;
@end
A.m文件
#import "PeopleA.h"
@implementation PeopleA
-(void)doSometing:(void (^)())someOne{
NSLog(@"A去理发");
if (someOne){
NSLog(@"找到了理发师");
someOne();
NSLog(@"理发师给我剪完头发了");
}else{
NSLog(@"没有找到理发师");
}
}
@end
B.h文件
@interface PeopleB : NSObject
-(void)doWork;
@end
B.m文件
#import "PeopleB.h"
#import "PeopleA.h"
@implementation PeopleB
-(void)doWork{
PeopleA* p = [PeopleA new];
[p doSometing:^{
NSLog(@"我现在给A剪发,我给他这样这样剪");
}];
}
@end
主调函数.m文件部分代码
PeopleB* p = [PeopleB new];
[p doWork];
下面是输出结果
# A去理发
# 找到了理发师
# 我现在给A剪发,我给他这样这样剪
# 理发师给我剪完头发了
1.要注意定义block的语法,定义的block可以有返回值,可以有参数,例如:-(void)doMethod:(int(^)(CGFloat numb, UIImage* image)) block;
就是定义了一个没有返回值的,参数为返回值为int类型的block函数,并且block含有numb和image两个参数。
2.注意,在block调用的时候,看看block是否存在,有可能没有实现代码,用if (block)
去判断,存在再去调用,不然会出错。
3.block匿名函数可以做任何变量,可以做函数参数,做属性,做返回值等。
--
现在我们说一下用block实现链式编码
关于链式编码,最常见的就是Masonry第三方库,写约束真是方便。
[button mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(0);
make.top.mas_equalTo(40);
make.width.mas_equalTo(100);
}];
在OC语言中,点语法,其实就是调用属性的set和get方法;我们可以直接设置为属性,也可以直接设置get方法,属性系统自动就给添加了。
下面我就写一个在网上最常见的案例,加减乘除计算的链式代码
Calculator.h文件
@interface Calculator : NSObject
@property(nonatomic)float result;
-(Calculator*(^)(float))add;
-(Calculator*(^)(float))sub;
-(Calculator*(^)(float))div;
-(Calculator*(^)(float))multi;
@end
Calculator.m文件
#import "Calculator.h"
@implementation Calculator
-(instancetype)init{
if (self = [super init]) {
self.result = 0;
}
return self;
}
-(Calculator*(^)(float))add{
return ^Calculator*(float num){
_result += num;
return self;
};
}
-(Calculator*(^)(float))sub{
return ^Calculator*(float num){
_result -= num;
return self;
};
}
-(Calculator*(^)(float))div{
return ^Calculator*(float num){
if (num == 0){
NSAssert(num != 0, @"是0,不可以做被除数");
}
_result = _result / num;
return self;
};
}
-(Calculator*(^)(float))multi{
return ^Calculator*(float num){
_result = _result * num;
return self;
};
}
@end
主调函数的调用部分代码
Calculator* cal = [Calculator new];
cal.add(1).add(12).sub(1).div(1).multi(10);
NSLog(@"%f",cal.result);
调用的结果为
# 120.000000
这段链式代码,主要是说明首先是用()调用,需要返回block,接着.链式调用,在返回block调用后需要返回自己(self)
有时候在Masonry看到and,with关键子,其实就是一个block什么都不做,直接返回自己(self)即如下:
-(Calculator*(^)())and{
return ^Calculator*(){
return self;
};
}
-(Calculator*(^)())with{
return ^Calculator*(){
return self;
};
}
//代码链加上上述代码,对代码结果没有影响