1、block的基本概念及使用
blcok是一种特殊的数据结构,它可以保存一段代码,等到需要的时候进行调用执行这段代码,常用于GCD、动画、排序及各类回调。
Block变量的声明格式为: 返回值类型(^Block名字)(参数列表);
//声明一个没有传参和返回值的blcok void(^myBlock1)(void) ; //声明一个有两个传参没有返回值的blcok 形参变量名称可以省略,只留有变量类型即可 void(^myBlock2)(NSString *name,int age); //声明一个没有传参但有返回值的blcok NSString *(^myBlock3)(); //声明一个既有返回值也有参数的blcok int(^myBlock4)(NSString *name);
block的赋值: Block变量 = ^(参数列表){函数体};
//如果没有参数可以省略写(void) myBlock1 = ^{ NSLog(@"hello,word"); }; myBlock2 = ^(NSString *name,int age){ NSLog(@"%@的年龄是%d",name,age); }; //通常情况下都将返回值类型省略,因为编译器可以从存储代码块的变量中确定返回值的类型 myBlock3 = ^{ return @"小李"; }; myBlock4 = ^(NSString *name){ NSLog(@"根据查找%@的年龄是10岁",name); return 10; };
当然也可以直接在声明的时候就赋值: 返回值类型(^Block名字)(参数列表) = ^(参数列表){函数体};
int(^myBlock5)(NSString *address,NSString *name) = ^(NSString *address,NSString *name){ NSLog(@"根据查找家住%@的%@今年18岁了",address,name); return 18; };
blcok的调用:Block名字();
//没有返回值的话直接 Block名字();调用 myBlock1(); //有参数的话要传递相应的参数 myBlock2(@"校花",12); //有返回值的话要对返回值进行接收 NSString *name = myBlock3(); NSLog(@"%@",name); //既有参数又有返回值的话就需要即传参数又接收返回值 int age = myBlock5(@"河北村",@"大梨"); NSLog(@"%d",age);
在实际使用Block的过程中,我们可能需要重复地声明多个相同返回值相同参数列表的Block变量(blcok内部执行的代码功能不一样),如果总是重复地编写一长串代码来声明变量会非常繁琐,
所以我们可以使用typedef来定义Block类型。
#import "ViewController.h" typedef void(^commentBlock)(NSString *name,int age); @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; commentBlock commentBlock1 = ^(NSString *name,int age){ //这里的操作是将age的name从数据库中筛选出来 }; commentBlock commentBlock2 = ^(NSString *name,int age){ //这里的操作是将age的name添加到数据库 }; commentBlock commentBlock3 = ^(NSString *name,int age){ //这里的操作是将age的name从数据库中删除 }; commentBlock1(@"li",12); commentBlock2(@"dong",19); commentBlock3(@"mi",8); } 这样可以减少重复代码,避免重复用void(^commentBlock)(NSString *name,int age);声明blcok
上面,只是讲到了blcok的一些基本使用,那么在我们实际开发中,block是怎么应用的呢?其实在实际开发中把block作为方法的参数是一种比较常见的用法,比如我们用到的网络请求工具.
比如,我们举一个block作为参数的小例子:
1 #import "ViewController.h" 2 typedef void(^BtnBlock)(void); 3 @interface ViewController () 4 @property(nonatomic,weak)BtnBlock currentBlcok; 5 @end 6 7 @implementation ViewController 8 9 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ 10 [self alertWithBlcok:^{ 11 NSLog(@"用户点击了确定 在这里可以执行对应的操作"); 12 }]; 13 // [self alertWithBlcok:nil]; 14 } 15 - (void)alertWithBlcok:(BtnBlock)block{ 16 _currentBlcok = block; 17 //低层最大的背景View 18 UIView *alertBgView = [[UIView alloc]initWithFrame:self.view.bounds]; 19 alertBgView.tag = 99; 20 alertBgView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.73]; 21 [self.view addSubview:alertBgView]; 22 23 //中间的View 24 UIView *alertCenterView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 240, 140)]; 25 alertCenterView.clipsToBounds = YES; 26 alertCenterView.layer.cornerRadius = 10; 27 alertCenterView.center = alertBgView.center; 28 alertCenterView.backgroundColor = [UIColor redColor]; 29 [alertBgView addSubview:alertCenterView]; 30 31 32 //取消按钮 33 UIButton *cancelBtn = [[UIButton alloc]initWithFrame:CGRectMake(0, 100, alertCenterView.frame.size.width/2, 40)]; 34 [cancelBtn setTitle:@"取消" forState:UIControlStateNormal]; 35 cancelBtn.titleLabel.font = [UIFont systemFontOfSize:15]; 36 [cancelBtn setTitleColor:[UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1.0] forState:UIControlStateNormal]; 37 [cancelBtn addTarget:self action:@selector(dismissAlertView) forControlEvents:UIControlEventTouchUpInside]; 38 [alertCenterView addSubview:cancelBtn]; 39 40 //短的分割线 41 UIView *shortView = [[UIView alloc]initWithFrame:CGRectMake(alertCenterView.frame.size.width/2, 110, 1, 20)]; 42 shortView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.53]; 43 [alertCenterView addSubview:shortView]; 44 45 //取消按钮 46 UIButton *continueBtn = [[UIButton alloc]initWithFrame:CGRectMake(alertCenterView.frame.size.width/2, 100, alertCenterView.frame.size.width/2,40)]; 47 [continueBtn setTitle:@"确定" forState:UIControlStateNormal]; 48 [continueBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 49 continueBtn.titleLabel.font = [UIFont systemFontOfSize:15]; 50 [continueBtn addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside]; 51 [alertCenterView addSubview:continueBtn]; 52 } 53 - (void)dismissAlertView{ 54 [[self.view viewWithTag:99] removeFromSuperview]; 55 } 56 -(void)buttonAction{ 57 if (_currentBlcok) { 58 _currentBlcok(); 59 } 60 }