block
1.block 是一个数据类型,所以我们可以声明一个block类型的变量.
2.block 类型的变量是专门存储一段代码的,这段代码可以有参数,也可以有返回值.
block变量的声明
在声明block变量的时候,必须要指定这个block变量存储的代码段是否有返回值,是否有参数,一旦指定以后,这个block变量中就只能存储这样的代码了.
就比如,声明了一个block变量,返回值是void,参数是一个int类型的,这个时候,这个block变量中就只能存储无返回值并且有一个int参数的代码段.
声明block变量的语法格式
返回值类型 (^block变量的名称)(参数列表)
void(^myBlock1)()
表示声明了一个变量名为myBlock1,没有返回值并且没有参数的block变量.
int(^myBlock2)()
表示声明了一个变量名为myBlock2,返回值为int类型但是没有参数的block变量.
int(^myBlock3)(int num1,int num2)
表示声明了一个变量名为myBlock3,返回值为int类型并且有两个int类型参数的block变量.
代码段的书写格式
^返回值类型(参数列表){
代码段;
};
一个无返回值无参数的代码段
^void(){
NSLog(@“我爱你”);
NSLog(@“我恨你”);
};
void(^myBlock1)();
myBlock1 = ^void(){
NSLog(@“我爱你”);
NSLog(@“我恨你”);
};
这个时候就可以把这段无返回值无参数的代码段赋值给这个无返回值无参数的myBlock1变量了.
也可以直接写成
void(^myBlock1)()= ^void(){
NSLog(@“我爱你”);
NSLog(@“我恨你”);
};
一个无参数有返回值的代码段
^int(){
int num1 = 10+20;
return num1;
};
int(^myBlock2)();
myBlock2 = ^int(){
int num1 = 10+20;
return num1;
};
这个时候就可以把这段有返回值无参数的代码段赋值给这个有返回值没有参数的myBlock2变量了.
也可以直接写成
int(^myBlock2)()= ^int(){
int num1 = 10+20;
return num1;
};
一个有返回值有参数的代码段
^int(int num1,int num2){
int num3 = num1+num2;
return num3;
};
int(^myBlock3)(int num1,int num2);
myBlock3 = ^int(int num1,int num2){
int num3 = num1+num2;
return num3;
};
这个时候就可以把这段有返回值有参数的代码段赋值给这个有返回值有参数的myBlock3变量了.
也可以直接写成
int(^myBlock3)(int num1,int num2)= ^int(int num1,int num2){
int num3 = num1+num2;
return num3;
};
如何执行存储在block变量中的代码段?
语法格式:block变量名();
有参数就传参数,有返回值就接.
myBlock1();
int num = myBlock2();
int sum = myBlock3(10,20);
关于block的简写
1.无论代码段是否有返回值,都可以不写返回值类型,如果在写代码的时候,省略了返回值,这个时候系统会自动的确定返回值的类型.
如果代码段中没有返回任何数据,那么它会认为这个代码段是没有返回值的.
如果代码段中有返回数据,返回的数据是什么类型,它就会认为这个代码段返回的是什么类型的.
void(^myBlock1)()= ^(){
NSLog(@“我爱你”);
NSLog(@“我恨你”);
};
int(^myBlock2)()= ^(){
int num1 = 10+20;
return num1;
};
int(^myBlock3)(int num1,int num2)= ^(int num1,int num2){
int num3 = num1+num2;
return num3;
};
2.如果我们写的代码段没有参数,那么代码段的小括弧,那么代码段的小括弧可以省略.
void(^myBlock1)()= ^{
NSLog(@“我爱你”);
NSLog(@“我恨你”);
};
int(^myBlock2)()= ^{
int num1 = 10+20;
return num1;
};
3.声明block变量的时候,如果有指定参数,可以只写参数的类型而不写参数的名称.
int(^myBlock3)(int,int)= ^(int num1,int num2){
int num3 = num1+num2;
return num3;
};
注意:这个地方代码段的类型和名称都要写.
建议:虽然可以简写,但是还是按照最标准的写法来写block变量和block代码段,因为这样可以提高代码的阅读性.
将一个复杂的长类型定义为一个短类型typedef的使用场景是将一个复杂的长类型定义为一个短类型.
简化block变量的复杂定义
遇到的问题是,定义block变量的时候,要写很大一串,所以可以使用typedef来自定义为短类型.
语法格式 : typedef 返回值类型 (^新类型)(参数列表);
typedef void(^NewType1)();//代表重新定义了一个类型叫做NewType1是一个无返回值无参数的block类型
NewType1 block1 = ^void(){
NSLog(@“我爱你”);
NSLog(@“我恨你”);
}
typedef int(^NewType2)();//代表重新定义了一个类型叫做NewType2是一个有返回值无参数的block类型
NewType2 block2 = ^int(){
int num1 = 10+20;
return num1;
}
typedef int(^NewType3)(int num1,int num2);//代表重新定义了一个类型叫做NewType3是一个有返回值有参数的block类型
NewType3 block3 = ^int(int num1,int num2){
int num3 = num1 + num2;
return num3;
};
关于block块访问外部变量的问题
1.在block代码块的内部可以取定义在外部变量的值,这个外部变量既可以是局部变量也可以是全局变量.
2.在block代码块的内部可以修改外部全局变量的值,但是不能修改外部的局部变量的值.
在block代码块的内部不能修改外部的局部变量的值3.如果是一定要在block代码块的内部修改外部的局部变量的值,就在外部的局部变量前加一个__block 修饰这个局部变量.
__block 修饰这个局部变量后 可以修改这个外部的局部变量的值block作为函数的参数block可以作为函数的参数
block也可以作为函数的返回值
typedef void(^NewType)();
NewType test(){
void(^block)()= ^void(){
NSLog(@“~~~~~~~~”);
NSLog(@“~~~~~~~~”);
NSLog(@“~~~~~~~~”);
};
return block;
}
block与函数
相同点:都是封装一段代码.
不同点:1.block是一个数据类型 2.block可以作为函数的参数,而函数不能直接作为函数的参数 3.可以声明block类型的变量
网友评论