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++源码查看:

 xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 MYBlock.m 
 
 


最新文章

  1. ORA-01034:ORACLE not available问题的解决方法
  2. tomcat 部署spring工程乱码解决方案
  3. js浏览器检测
  4. MyBatis XML 映射配置文件
  5. sqlserver 存储过程 以及统计整个数据库数据
  6. JS中URL编码参数(UrlEncode)
  7. 用特殊字体来实现矢量ICON
  8. Python3.5入门学习记录-File
  9. 懒与馋的平衡:餐饮O2O市场广阔,发展不易
  10. 基于binlog来分析mysql的行记录修改情况(python脚本分析)
  11. h5 录音
  12. Java中的throw和throws的区别
  13. rcnn fast-rcnn faster-rcnn资料
  14. [USACO12OPEN]书架Bookshelf
  15. angular 表单验证
  16. 老版本db2这里下
  17. C++Primer第五版——习题答案目录
  18. Verilog风格
  19. 动软 生成 linq相关DAO
  20. Django2.0路由层-URLconf

热门文章

  1. Java生鲜电商平台-一次代码重构的实战案例
  2. JVM 学习总结
  3. body的背景
  4. android studio学习----gradle多渠道打包
  5. linux源代码获取
  6. MySQL的过滤(极客时间学习笔记)
  7. 155--MinStack
  8. 逆向破解之160个CrackMe —— 010-011
  9. 笔记3:MySQL数据库
  10. jmeter压测学习6-HTTP Cookie管理器