block理解
block:https://www.jianshu.com/p/da96ec752aee
1.对于 block 外的变量引用,block 默认是将其复制到其数据结构中来实现访问的。也就是说block的自动变量截获只针对block内部使用的自动变量, 不使用则不截获, 因为截获的自动变量会存储于block的结构体内部, 会导致block体积变大。特别要注意的是默认情况下block只能访问不能修改局部变量的值。(block访问的值不会跟随外部的修改而变化---值传递)
2.当访问的变量为静态值(static)时,此时block内部引用局部变量是通过指针来访问的,所以外部的重新赋值,将导致block内变量的改变
对于用 __block 修饰的外部变量引用,block 是复制其引用地址来实现访问的。block可以修改__block 修饰的外部变量的值。(指针传递)
3。访问全局变量和访问静态值结果相同,全局变量存放在静态存储区,不同的时,全局变量是直接访问;
ARC下block属性的建议写法:
@property (strong, nonatomic) void (^block)(void);
@property (copy, nonatomic) void (^block)(void);
以上的写法系统会自动帮我们将block从栈区拷贝到堆区;这样可以避免在调用block时,block访问的局部变量被释放后产生的异常;
原因:一个局部变量加上__block修饰符后将变成了一个__Block_byref_val_0结构体类型的自动变量实例!!!!(此时局部变量和block是同一类型结构体)
此时我们在block内部访问val变量则需要通过一个叫__forwarding的成员变量来间接访问val变量。
全局block相当于单例放在全局内存中;
Block不访问外界变量,放在代码段中,为全局块;
ARC 环境下:访问外界变量的 Block 默认存储在堆中(实际是放在栈区,然后ARC情况下自动又拷贝到堆区),自动释放。
Block的复制操作执行的是copy实例方法。Block只要调用了copy方法,栈块就会变成堆块。在ARC有效时,多次调用copy方法完全没有问题。
block的位置,只测试arc下:
1 创建block对象后,在未使用局部变量时,赋值后的block位于全局区域(NSGlobalBlock), 引用局部变量后,block位于堆区 (NSMallockBlock);
对block只是声明对情况下,在未使用局部变量时,赋值后的block位于全局区域,
引用局部变量后,位于栈区;
注:在不确定block位于栈区或者堆区时,直接copy,保证block在堆区,再使用,避免crash;
使用__block后可以在block内部修改局部变量的理解:
参考:https://juejin.im/post/5ae40763f265da0ba062e842
当局部变量添加__block后,原生c代码会将基本数据类型变为一个struct,在使用block过程中,引用了此局部变量后,会将此struct复制到堆上,并且栈上的局部变量此时的struct中的__forwarding指向的是复制到堆上的struct上的变量的地址;而堆上的局部变量的struct中__forwarding则指向自己的变量;所以此时在block中修改局部变量值,block外部局部变量对应改变;
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
· 程序员转型AI:行业分析
· 重磅发布!DeepSeek 微调秘籍揭秘,一键解锁升级版全家桶,AI 玩家必备神器!