iOS block疑难解答
1,为什么需要加__block
ARC环境下,一旦Block赋值就会触发copy,__block就会copy到堆上,Block也是__NSMallocBlock。ARC环境下也是存在__NSStackBlock的时候,这种情况下,__block就在栈上。ARC环境下,Block捕获外部对象变量,是都会copy一份的,地址都不同。只不过带有__block修饰符的变量会被捕获到Block内部持有。
MRC环境下,只有copy,__block才会被复制到堆上,否则,__block一直都在栈上,block也只是__NSStackBlock,这个时候__forwarding指针就只指向自己了。
int main(int argc, const char * argv[])
{ __block id block_obj = [[NSObject alloc]init];
id obj = [[NSObject alloc]init];
NSLog(@"block_obj = [%@ , %p] , obj = [%@ , %p]",block_obj , &block_obj , obj , &obj);
void (^myBlock)(void) = ^{
NSLog(@"***Block中****block_obj = [%@ , %p] , obj = [%@ , %p]",block_obj , &block_obj , obj , &obj);
};
myBlock();
return 0;
}
对于非对象的变量来说,
自动变量的值,被copy进了Block,不带__block的自动变量只能在里面被访问,并不能改变值。
带__block的自动变量 和 静态变量 就是直接地址访问。所以在Block里面可以直接改变变量的值。
而剩下的静态全局变量,函数参数,也是可以在直接在Block中改变变量值的,但是他们并没有变成Block结构体__main_block_impl_0的成员变量,因为他们的作用域大,所以可以直接更改他们的值。 静态全局变量,全局变量,函数参数他们并不会被Block持有,也就是说不会增加retainCount值。
对于对象来说 在MRC环境下,__block根本不会对指针所指向的对象执行copy操作,而只是把指针进行的复制。
而在ARC环境下,对于声明为__block的外部对象,在block内部会进行retain,以至于在block环境内能安全的引用外部对象。
当block
内部访问了对象类型的auto
变量时:
1:如果block
是在栈上,将不会对auto
变量产生强引用(不管是 MRC 或者 ARC)
2:如果block
是在堆上,就说明block
进行过copy
操作,进行copy
操作的block
会自动调用block内部的__main_block_copy_0
函数,__main_block_copy_0
函数内部会根据auto
变量的修饰符形成相应的强引用(retain
)或者弱引用.
3:当block
销毁时,block
会自动调用内部的dispose
函数,dispose
函数会自动调用内部的__main_block_dispose_0
释放引用的auto
变量.
oc转c++源码查看:
最新文章
- ORA-01034:ORACLE not available问题的解决方法
- tomcat 部署spring工程乱码解决方案
- js浏览器检测
- MyBatis XML 映射配置文件
- sqlserver 存储过程 以及统计整个数据库数据
- JS中URL编码参数(UrlEncode)
- 用特殊字体来实现矢量ICON
- Python3.5入门学习记录-File
- 懒与馋的平衡:餐饮O2O市场广阔,发展不易
- 基于binlog来分析mysql的行记录修改情况(python脚本分析)
- h5 录音
- Java中的throw和throws的区别
- rcnn fast-rcnn faster-rcnn资料
- [USACO12OPEN]书架Bookshelf
- angular 表单验证
- 老版本db2这里下
- C++Primer第五版——习题答案目录
- Verilog风格
- 动软 生成 linq相关DAO
- Django2.0路由层-URLconf