block的创建
- 使用 ^ 操作符来声明一个 block 变量和指示 block 文本的开始。block 本身的主体被 {} 包含着,类似于C语言函数的声明
block声明:
返回类型 (^方法名字) (参数名字,...)
block实现
方法名字 = ^(参数类型 参数名)
{
实现内容
}
- block简单的用法
1.当做参数进行传递
-(void)funtion:(int ^()(int))block
typedef int (^myblock)(int)
-(void)funtion:(myblock)block
2.使用block进行回调
思路很简单 ,B类想给A类回调信息 ,那就应该在B类声明block,在B类中调用Block,在A类中实现Block
B.h
//声明一个block 返回值为空 ,参数为id类型的obj,其中obj就是我们要回传的数据
typedef void (^SuccessBlock)(id obj);
B.m
调用SuccessBlock(@"123");
A.m
[b alloc].SuccessBlock = ^(id obj){
NSLog(%@,obj);
}
//或者是通过函数的参数进行调用
B.h
typedef void (^SuccessBlock)(id obj);
+(void)getSucceesString:(SuccessBlock)block;
B.m
+(void)getSucceesString:(SuccessBlock)block{
block(@"123");
}
A.m
[b getSucceesString:^(id obj){
NSLog(%@,obj);
}];
block的实现原理
[参考文章](http://www.jianshu.com/p/f12a3b023504,http://www.tuicool.com/articles/vy2ARnj)
block的存储形态有三种:_NSConcretStackBlock(栈)、_NSConcretGlobalBlock(全局)、_NSConcretMallocBlock(堆)
要点一:当block在函数内部,且定义的时候就使用了函数内部的变量,那么这个 block是存储在栈上的。
要点二:当block定义在函数体外面,或者定义在函数体内部且当时函数执行的时候,block体中并没有需要使用函数内部的局部变量时,也就是block在函数执行的时候只是静静地待在一边定义了一下而不使用函数体的内容,那么block将会被编译器存储为全局block。
要点三:全局block存储在堆中,对全局block使用copy操作会返回原函数指针;而对栈中的block使用copy操作,会产生两个不同的block地址,也就是两个匿名函数的入口地址。
要点四:ARC机制优化会将stack的block,转为heap的block进行调用。