今日更加仔细的学习了block的使用方法,真是大开眼界,以前都不知道block这么强大,下面仔细说下,有不足的希望大家多多指教!
先说一下block定义方法:
returnType(^blockName)(parameterTypes) = ^(parameters) {
statements
};
使用方法一
把block保存到对象中,在恰当时机调用。
//定义
typedef void(^blockName)();
@property(nonatomic,copy)blockName block1;
@property(nonatomic,copy)void(^blockTest1)();
@property(nonatomic,copy)void(^block2)();
//带参数的
@property(nonatomic,copy)void(^block3)(int);
@property(nonatomic,copy)void(^block4)(int, NSString *,BOOL);
@property(nonatomic,copy)NSString *(^block5)(int, NSString *);
//实现以及调用
-(void)blockUse1
{
void(^blockName)() = ^{
NSLog(@"-----block第一种用法");
};
//调用
blockName();
_blockTest1 = blockName;
_block3 = ^(int m){
NSLog(@"%d -- 米",m);
};
_block4 = ^(int m, NSString * str, BOOL isYes){
NSLog(@"%d, %@, %d",m, str, isYes);
};
//带有参数和返回值的block实现
_block5 = ^NSString *(int m, NSString * str){
return [NSString stringWithFormat:@"%d -- %@",m, str];
};
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
_blockTest1();
_block3(5);
_block4(4, @"hello",YES);
NSString * str = _block5(10, @"Hello");
NSLog(@"----%@",str);
}
使用方法二
block充当方法的参数。
特点:在方法内部调用block,外部实现block。
//使用2:把block当做方法的参数使用,由方法外部实现,内部调用
//block 无参数
-(void)eat:(void(^)())block;
//block 有参数
-(void)eat:(void(^)(int))block1 apple:(void(^)(int))block2;
//block 有参数,有返回值
-(void)run:(int(^)(int))block;
//方法实现,block调用
-(void)eat:(void (^)())block
{
//调用
block();
}
-(void)eat:(void (^)(int))block1 apple:(void (^)(int))block2
{
block1(5);
block2(10);
}
-(void)run:(int (^)(int))block
{
int a = block(10);
NSLog(@"run -- a :%d", a);
}
//block实现
-(void)blockUser2
{
//可以反向传值
Person * p = [[Person alloc]init];
//1.block 无返回值,无参数
[p eat:^{
NSLog(@"blockUse2 -- 吃东西");
}];
//2.block无返回值,有参数
[p eat:^(int m) {
NSLog(@"m -- %d",m);
} apple:^(int n) {
NSLog(@"n -- %d",n);
}];
int(^bb)(int) = ^int(int m){
return m+5;
};
int b = bb(5);
//3.block有返回值,有参数
[p run:^int(int m) {
return m+10;
}];
}
使用方法三
block充当方法的返回值。
特点:在方法内部实现block,外部调用block。
目的是为了替代方法,实现了 链式编程。
//1.block无返回值,无参数
-(void(^)())eat;
//2.block无返回值,有参数
-(void(^)(int, NSString *))eatMany;
//3.block有返回值,有参数,可以得到返回值
-(int(^)(int))run;
-(void (^)())eat
{
return ^{
NSLog(@"block3 -- block做方法返回值 -- ");
};
}
-(void (^)(int, NSString *))eatMany
{
return ^(int m, NSString * str){
NSLog(@"eat - %d, I am %@", m, str);
};
}
-(int (^)(int))run
{
return ^int(int m){
return m + 10;
};
}
//外部调用
-(void)blockUse3
{
Person * p = [[Person alloc]init];
//1.block无返回值,无参数
p.eat();
//2.block无返回值,有参数
p.eatMany(5, @"Happy");
//3.block有返回值,有参数,可以得到返回值,可以在调用的时候把值传过去,再接受处理后的值,和以前的带参且有返回值的方法调用原理一样
int a = p.run(10);
NSLog(@"a current value -- %d",a);
}
使用方法四(最容易混乱的方法)
特点:block既充当方法参数,又充当方法返回值!
//方法定义
-(NSString *(^)(NSString *))swimMeter:(int(^)(int))block;
//方法实现
-(NSString *(^)(NSString *))swimMeter:(int (^)(int))block
{
int meter = block(10);
return ^NSString *(NSString * str){
return [NSString stringWithFormat:@"小明-- %@ -- %d meter",str, meter];
};
}
//外部调用
NSString *(^block)(NSString *str) = [p swimMeter:^int(int meter) {
return meter += 10;
}];
NSString * str = block(@"swims");
NSLog(@"%@",str);
注意:
方法四外部首先要实现参数block,然后再调用返回值block!