Block 是苹果公司较晚推出的一个语法,与很多语法的闭包差不多意思
一:Block声明
PS:很多人学不好Block,大概率是被它的声明写法给吓到了,写法确实有点奇怪
objectivec
返回值类型(^block变量名)(参数列表)
例如: int(^personBlock)(NSString *,int)
objectivec
返回值类型(^block变量名)(参数列表)
int(^personBlock)(NSString *,int)
返回值类型:int
block变量名: personBlock
参数列表:NSString *,int
(注意:参数列表只需要写参数类型,不需要写参数名,例如:NSString * name 的写法是不对的,不需要写参数名name)
这句代码的意思是:声明了一个类型为Block,名字叫 personBlock 的变量, 这个变量有返回值,返回值的类型为int,同时它还可以接受参数,参数为NSString * , int
如何还不理解上面的那段话,可以配合下面两段理解
int age; 声明了一个 类型为 int,名字叫age 的变量 (不同的是,它没有返回值)
NSString * name; 声明了一个类型为NSString,名字叫叫name的变量 (不同的是,它没有返回值)
明白了上面的声明写法,那么Block的声明就可以随意发挥了,例如:
objectivec
//声明一个空返回值,没有参数的block
void (^aBlock)(void)
//声明一个空返回值,参数有NSString *,NSString *,NSString *,int 的block
void(^bBlock)(NSString *,NSString *,NSString *,int);
//声明一个返回类型为NSString,参数有int 的block
NSString* (^cBlock)(int)
二:Block的定义+实现
上面讲了Block的声明,接下来定义:
objectivec
返回值类型(^block变量名)(参数列表) = ^(参数列表) {
};
上Block的声明写到"=" 前面的"参数列表"只需要写参数类型,不需要写参数名.
"="后面的 "参数列表" 则需要写参数类型+参数名,例如:
objectivec
- (void)viewDidLoad
{
[super viewDidLoad];
NSString * (^personBlock)(NSString *,int) = ^(NSString * name, int age){
NSLog(@"年龄==%d",age);
return name;
};
//实现
NSString * name = personBlock(@"zhangsan",29);
NSLog(@"姓名==%@",name);
}
定义了一个返回类型为NSString,参数类型为NSString *,int 的 block,
实现的时候跟实现方法调用一样
Block的声明+定义+实现 补充
常用的Block是用别名 typedef 的方式声明,与 @property 声明变量的方式差不多,例如:
objectivec
#import "ViewController.h"
//使用别名的方式声明一个block
typedef void(^ PersonBlock) (int,NSString *);
@interface ViewController ()
@end
使用: 和结构题的使用方法差不多
objectivec
- (void)viewDidLoad
{
[super viewDidLoad];
PersonBlock pblock = ^(int age,NSString * name) {
NSLog(@"年龄==%d,姓名==%@",age,name);
};
pblock(10,@"lisi");
}
三:Block的对变量的使用
Block可以对外部的变量进行使用,
objectivec
- (void)viewDidLoad
{
[super viewDidLoad];
int c = 20;
int(^myBlock)(int,int) = ^(int a,int b ){
//可以使用外部的c,例如:打印c,使用
NSLog(@"c==%d",c);
//又或者拿来做算术
int d = a + b + c;
return a+b;
};
}
但是不能改变,如果非要改变,那么就需要在被改变的参数前加 __block.
在定义C的时候,在其前面加上__block 即可,例如:
objectivec
__block int c = 20;
int(^myBlock)(int,int) = ^(int a,int b ){
//如果不对c做处理,直接改变,则会报错
c = 30;
return a+b;
};
四:Block使用场景
4.1.用作参数
4.2.用作返回值
彩蛋:xcode 为 block创建了一个代码块快捷键:在xcode上输入 inline,按回车,一个block的框架就出来了: