Blocks Programming Topics
官方介绍
Block objects are a C-level syntactic and runtime feature. They are similar to standard C functions, but inaddition to executable code they may also contain variable bindings to automatic (stack) or managed (heap)memory. A block can therefore maintain a set of state (data) that it can use to impact behavior when executed.
简单来说就是一段代码,也是一个对象。
那么这里提到的Objecttive-C++,解释如下:
Objective-C++ is simply source code that mixes Objective-C classes and C++ classes (two entirely unrelatedentities). Your C++ code will work, just as before, and the resulting executable will be linked with the Objective-Cruntime, so your Objective-C classes will work as well. You can definitely use it in XCode -- name your files withthe .mm extension.
使用 ^ 来表示一个Block
int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
Block是一个结构体
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};
其结构体成员如下:
- isa,指向所属类的指针,也就是block的类型
- flags,标志变量,在实现block的内部操作时候会用到。
- Reserved,保留变量
- FuncPtr,block执行时调用的函数指针。 可以看出,包含了isa指针,指向的都是对象,也就是说block也是一个对象(runtime里面,对象和类都是用结构体表示)
Block的执行过程
开始之前先明白两个概念:stack 和 heap;
方法执行先进入stack中,在stack捕获变量,将block中的变量加上了const参数,成为了常量。因为这样想函数一样高效不占内存,然后将Block异步执行copy进入到heap中。
这时候进入heap中的是常量,常量是不能被改变的。如果我们需要对其改变并将这个变量加入block中,必须在变量前加上__block,不然会报错,如下:
有一个问题,如果对block执行两次copy,[block copy],这时候也只会在heap中创建一份常量。 还有一个问题是在代码块中使用self,如果代表实例对象的话,这个类对block有引用,因为执行一个block,用到了copy,也可以看做是strong引用,而block有对self引用引起了retain cycle 警告。
来一个最简单的block
:^{},如果执行的话加上();
int main(int argc, const char * argv[]) {
@autoreleasepool {
^{ NSLog(@"I am a block");}();
}
return 0;
}
Block的三种类型
- _NSConcreteGlobalBlock(全局)
- _NSConcreteStackBlock(栈)
- _NSConcreteMallocBlock(堆)
捕捉变量对block结构的影响
- 局部变量:不能在block中对其进行修改,生命周期同方法
- 全局变量:在静态数据存储区,生命周期同程序。
- 静态局部变量:生命周期同程序,储存在静态数据区域,
__block修饰
- 局部变量:为了操作的值始终是堆中的拷贝,不是栈中的值。也是为了能修改。
self引用循环
- 在Block使用的时候在前面添加weak弱引用,将循环引用断开