一、block本质是个对象,涉及闭包的概念,用于封装代码
int (^block)(int a,int b) = ^(int a,int b){ return a + b; };
定义: int (^block)(int a,int b)
参数: int
返回类型 int a
输出参数a
(名称可以不写) int b
输入参数b
(名称可以不写)实现:^(int a,int b){ return a + b; };
参数:int a,int b
(名称不可缺){}
实现
二、block由储存位置不同有的类型,这些类型只有编译器使用
- _NSConcreteStackBlock (NSStackBlock) 存储在栈上;
- _NSConcreteGlobalBlock (NSGlobalBlock) 存储在程序的代码段;
- _NSConcreteMallocBlock (NSMallocBlock) 存储在堆上。
- 知识提示:C语言中储存有程序代码区(text)、全局区(静态)、常量区、栈区(stack)、堆区(heap,使用malloc)
说明:
- NSGlobalBlock:在block内部没有引用任何外部变量
- NSStackBlock:在block内部引用外部变量,处于栈上的block会随栈退出,引用导致崩溃。
- NSMallocBlock:在其作用域外部使用的指针增加(copy、rerain)
注意:在arc情况下,没有NSStackBlock这个类型,如果有系统自动copy成为NSMallocBlock,同时拷贝代码内部变量如:
int base = 2;
base += 2; // base->4
long (^sums)(int,int) = ^ long (int a,int b){
return base + a + b; //base->4
};
base ++; //base->5
NSLog(@"%ld",sums(1,2));//输出的结果为 7 arc下提前拷贝base
经典事例,自带答案
三、引用问题:只有NSMallocBlock支持retain、release操作 (老生常谈了具体自己搜吧)
- block 内部代码修改数据情况:__block修饰、static
- 循环引用的问题:block代码段强引用,使用 __weak typeof (self) weakSelf = self;
- block对象被提前释放:不要用__block