对于block的运用必须了解他存储的区域, 才能更好的利用.
block在运用过程中存储状态有3种:
//1.<__NSGlobalBlock__: 0x100004250>, 静态区,
//1. MRC下当声明的block实现部分, 没有引入外界的任何局部变量, 或者引入全局变量或者static变量, 那么该block位于全局静态区, 此时block的内存不需要程序员管理, 程序运行完, 内存被系统回收
static int a = 20;
void (^myBlock)() = ^{
NSLog(@"Hello, World!, a = %d", a);
};
NSLog(@"%@", myBlock);
a = 30;
p1.age = 43;
myBlock();
这段代码中a为静态变量, 存于全局静态区, block函数内部没有引入任何局部变量(包括对象), 这是的打印结果就是:
显然block存储于静态区;
并且, 在全局静态区的block执行copy后依然存放于全局静态区,
且, 上述代码可以看到函数调用前对变量的值进行修改结果会跟着改变.
这是因为:block, 从底层上讲, 是一个指向结构体的指针
// *当我们局部变量前面加上static和__block或者是一个全局变量的时候, 他们传入结构体的时候相当于传入一个变量的指针, 所以当我们在调用之前改变a得值得时候, 结果会发生变化.
//2.<__NSStackBlock__: 0x7fff5fbff7f8>, 栈区
//2.当block中引入局部变量(包含基础类型和局部类型), 此时block位于栈区, 出了函数的作用域, 该内存就被释放掉了, 只执行回调的时候, 使用栈区的block很危险, 容易造成也指针问题, **为什么block使用copy的原因
int a = 20;
void (^myBlock)() = ^{
NSLog(@"Hello, World!, a = %d", a);
};
a = 30;
myBlock();
此代码中, a为局部变量, block存放于栈区, 打印结果,
此时, 打印结果中可以看出, 打印前虽然对a的值进行了修改, 但是结果却并没有改变;
因为此时block中传入的局部变量相当于直接将常量20放入block函数的实现体中, 所以改变了a的值, 并不会对block内部产生影响
//3.<__NSMallocBlock__: 0x100100340>, 堆区
//3.对栈区的block进行copy操作, 此时block的内存就会由栈区迁徙到堆区, 我们队位于全局静态区的block进行copy, 此时还在全局静态区
int a = 20;
void (^myBlock)() = ^{
NSLog(@"Hello, World!, a = %d", a);
};
NSLog(@"%@", [myBlock copy]);
a = 30;
myBlock();
打印结果:
今天的block小结就先总结这么多, 希望大家对此文多多评论, 多多补充.
本人现学习中, 了解颇浅, 请诸位海涵...