------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Block类型是一个C级别的语法和运行机制,不是OC特有。Block对象包含着一组状态数据,这些数据在程序执行时用于对行为产生影响。作为一个回调,block特别有用,因为block既包含了回调期间的代码,又包含了执行期间需要的数据。而且,block被设计为同时兼容OC、C和C++三种语言。
用^操作符来声明一个Block变量,并指明Block述句的开始。Block的主体包含在{}内。与C语法一样,“:”指明语句的结束。
1)有参无返回值
格式:
格式:
void (^block变量名)(参数类型及个数) = ^(形参列表){
代码块的语;
};
示例:
//定义一个变量myblock2 同时进行赋值
void (^myblock2)(int,int)=^(int a,int b){
NSLog(@"a + b = %d", a+b);
};
myblock2(34,12);
//先定义变量,再赋值
myblock2 = ^(int x,int y){
int m = x>y?x:y;
NSLog(@"max = %d",m);
};
myblock2(34,12);
2)有参有返回值
格式:
格式:
返回值类型 (^变量名)(参数类型及个数) = ^(形参列表){
代码块的语;
return ;
};
示例:
//定义
int (^myblock1)(int , int ) = ^(int x, int y){
return x+y;
};
//使用block,接收返回值
int a = myblock1(10,20);
NSLog(@"a = %d",a);
//给变量重新赋值
myblock1 =^(int x, int y){
return x*y;
};
a = myblock1(10,20);
NSLog(@"a = %d",a);
3)无参有返回值(略)
4)无参无返回值
格式:
//定义一个没有参数没有返回值的block变量,并且赋值了
void (^block变量名)() = ^(){
代码块的语;
};
//优化
void (^block变量名)() = ^{
代码块的语;
};
//block变量的使用:
block变量名();
示例:
//定义
void (^myBlock4)()=^(){
NSLog(@"XXXX");
};
//使用
myBlock4();
//优化
void (^myBlock5)()=^{
NSLog(@"****");
};
myBlock5();
利用typedef定义block类型
格式:
typedef 返回值类型 (^新别名)(参数类型列表);
示例:
//定义一个block变量,并且赋值
void (^myBlock)() = ^{
NSLog(@"helloworld");
};
myBlock();
//定义一个别名
//给 没有返回值 没有参数 的block起一个别名
//Block 是一个类型,不再是一个单纯的变量了
typedef void (^Block)();
Block b1;
b1 = ^{
NSLog(@"helloworld");
};
b1();
//定义有参数\有返回值的 block类型
//定义新的别名
//返回值是int 有两个int类型的参数
typedef int (^NewType1)(int ,int );
NewType1 nt1 = ^(int a,int b){
return a+b;
};
int s = nt1(12,23);
NSLog(@"s = %d",s);
//连续定义多个 NewType1类型的变量
NewType1 n1,n2,n3;
n1 = ^(int x,int y){
return x>y?x:y;
};
1)在block内部可以访问block外部的变量
在block内部可以使用block外部的变量,但是注意,这是一个新的内存空间
在block内部也可以定义和block外部同名的变量(局部变量),此时局部变量会暂时屏蔽外部变量的作用域
2)在block内部不可以修改block“外部的变量”
非局部变量会以const变量被拷贝并存储到block中,也就是说block对其是只读的。如果尝试在block内部给make变量赋值,会抛出编译器错误,block内部是只读的。而对于全局变量,则在block内部是可以被修改的。
如果在变量前加上_ _block,就不再以const的方式拷贝,允许改变值。修改之后,在block之后(包括外面)访问该变量,则取得的是修改后的值。
冻结中的非局部变量是一个常量值,这也是一种默认的安全行为——因为这可以防止在block中的代码对非局部变量做了意外的修改。
3)block有三种,即全局block,栈block,堆block。
步骤:
1)使用typedef 定义一个新的类型
//1)使用typedef 定义一个新的类型
typedef void (^newType)();
2)使用新类型作为函数的返回值
//2) 用新定义的类型作为函数的返回值
newType test(){
//定义block变量
newType w1 = ^{
NSLog(@"xxxx");
NSLog(@"helloworld");
};
return w1; //返回block
}
3)定义变量接收函数返回的值(block类型)
//3)定义block变量接收 函数返回的结果
newType n1 = test();
4)调用block
//4)执行block;
n1();
定义一个有参数有返回值的新类型,代码如下
//定义一个新的类型 newType
typedef int(^newType) (int ,int );
newType test(){
//返回一个特殊的“值”,这个值是一个有返回值,有两个参数的代码块
return ^(int a,int b){
return a+b;
};
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
newType n2 = test();
int s = n2(23,12);
NSLog(@"s = %d",s);
}
return 0;
}