block修改变量,有哪些方式你知道了吗?

简介: block修改变量

1、block修改变量

1、__block可以用于解决block内部无法修改auto变量值的问题

2、__block不能修饰全局变量、静态变量(static)

3、编译器会将__block变量包装成一个对象


1.1、直接修改变量?

代码示例:


#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        int age = 10;
        void(^block)(void) = ^{
//            age = 20;
            NSLog(@"Hello1:%d",age);
        };
        block();
    }
    return 0;
}

d47dee36332e48e8b001a356a1c8bf12.png

结果:

如果我们直接在block函数修改age变量的值,发现系统会直接报错,无法编译。


1.2、把auto变量改成static变量

这样block内部成员捕获的外部age成员的地址。这样在block内部修改值和赋值也是通过age地址处理的68ee45c834a1425cb55f7b37a68ad156.png

1.3、把auto变量改成全局变量

因为全局变量所有的函数都可以访问,block也不会去捕获全局变量到结构体中,直接在函数中取值赋值即可。


5a4bc95fe6f0475aba2abb901a1b4fcd.png

1.4、auto变量添加 __block 修饰符

很多时候我们并不想将auto变量改成static变量或全局变量,因为把变量改成全局变量或者static变量,这个变量是一直存在内存中的,不会被释放。这并不是我们想要的,所以我们还是希望他是临时变量,在不需要的时候可以自动销毁。那要怎么处理呢?这里就涉及到一个新的对象修饰符:__block。


见下图,添加 __block 修饰符是可以实现auto变量修改的:

4c1fbf2aebbd46879fc1ef42d3668fed.png

__block优势:


1、被修饰的变量可以在block函数中修改和访问。

2、被修饰的变量其性质没有被改变,还是自动变量。


那么加了 __block 修饰符之后,底层做了什么,让block函数内部可以正常修改auto变量?


2、添加 __block 修饰符之后的底层结构

// 程序入口
int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 
        // 1、用__block 修饰符,cpp底层直接将该auto变量转换成一个结构体对象
        __Block_byref_age_0 age = {
            0,// isa
            &age,//自己的地址
            0,// flags
            sizeof(__Block_byref_age_0),//当前结构体的大小
            10//外部传进来的变量值
            };
        // 2、定义block变量
        void(*block)(void) = 
          &__main_block_impl_0(// 2.1、block结构体
              __main_block_func_0,// 2.2、block函数
              &__main_block_desc_0_DATA,
              &age,//新定义的结构体变量
              570425344
           );
        block->FuncPtr(block);
    }
    return 0;
}
// 1、auto变量age的结构体
struct __Block_byref_age_0 {
  void *__isa;
__Block_byref_age_0 *__forwarding;//指向自己的指针
 int __flags;
 int __size;
 int age;// age结构体内部才拥有age变量
};
//2.1、block结构体
struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __Block_byref_age_0 *age; // 2.1a、此时block没有直接存储age变量,而是由age变量生成的结构体指针
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_age_0 *_age, int flags=0) : age(_age->__forwarding) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};
// 2.2、block函数
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
  // 2.2a、获取block中的age结构体对象
    __Block_byref_age_0 *age = __cself->age; // bound by ref
  //2.2b、赋值:取age的成员变量__forwarding(指向自己的指针),再取其中的age变量赋值
   (age->__forwarding->age) = 20;
     //2.2c、取值:跟赋值一个逻辑 
    NSLog((NSString *)&__NSConstantStringImpl__var_folders_vc_pn677_yj1sz8hgf_q5bjvssc0000gn_T_main_829ca2_mi_0,(age->__forwarding->age));
}


底层结构图:

885fff63923a4322a6e8e9a4b88d32fa.png


3、修改变量指针与使用变量指针的异同

如下图,是可以正常编译和赋值的:

989d0591ef4f4ba9a6802f3b28e73811.png

因为这两句代码不是在修改array变量的指针,而是在使用array指针。


[array addObject:@"123"];
[array addObject:@"321"];

1、使用auto变量的指针,不需要 __block ,只有在修改 auto变量的指针,才需要__block 修饰符修饰 auto变量。

2、能不加__block修饰符就不加,因为使用__block修饰符会生成一个新的对象来引用他。


相关文章
|
存储 缓存 监控
iOS 底层原理39:Instruments系列(一)Instruments介绍
iOS 底层原理39:Instruments系列(一)Instruments介绍
2311 0
iOS 底层原理39:Instruments系列(一)Instruments介绍
|
算法 计算机视觉
OpenCV(二十六):边缘检测(二)
OpenCV(二十六):边缘检测(二)
164 0
|
机器学习/深度学习 算法 TensorFlow
Py之imblearn:imblearn/imbalanced-learn库的简介、安装、使用方法之详细攻略
Py之imblearn:imblearn/imbalanced-learn库的简介、安装、使用方法之详细攻略
Py之imblearn:imblearn/imbalanced-learn库的简介、安装、使用方法之详细攻略
|
4月前
|
存储 机器学习/深度学习 边缘计算
OSS生命周期管理自动化:7天冷归档+30天低频访问的合规存储策略(结合企业级数据分级场景)
在数据爆炸增长背景下,企业面临存储成本攀升与合规要求升级的双重挑战。本文以金融与医疗行业实践为例,深入解析如何通过OSS自动化生命周期管理实现数据分级存储优化。内容涵盖数据热力模型分析、存储类型成本对比、状态机驱动的自动降级策略、合规性保障机制及机器学习动态预测方案,最终达成存储成本下降64.3%、合规审计通过率提升至98.7%的实战效果。适合关注云存储架构优化、数据治理与合规管控的技术决策者参考。
168 0
|
8月前
|
数据采集 机器学习/深度学习 人工智能
《深度剖析:AI与姿态估计技术在元宇宙VR交互中的应用困境》
在元宇宙中,虚拟现实(VR)交互依赖于人工智能(AI)与姿态估计技术的融合,以实现沉浸式体验。然而,复杂环境下的精准识别、实时性与计算资源矛盾、数据质量与隐私困境以及语义理解偏差等问题,严重制约了其发展。复杂背景、多人互动和快速动作变化导致姿态识别困难;高精度算法虽提升准确性,但计算复杂度高,影响实时反馈;高质量数据采集与标注难,且涉及隐私风险;AI对用户意图的理解不足,影响交互流畅性。解决这些难题是实现元宇宙VR交互智能化的关键。
146 3
|
9月前
|
搜索推荐 架构师 数据挖掘
架构实操:画好一张业务模型图
本文以SDK设计的角度分析了如何构建一张属于SDK的各个业务的模型图。
502 14
消费级显卡微调可图Kolors最佳实践!
近期,快手开源了一种名为Kolors(可图)的文本到图像生成模型,该模型具有对英语和汉语的深刻理解,并能够生成高质量、逼真的图像。
|
12月前
|
机器学习/深度学习 人工智能 自然语言处理
人工智能技术在金融领域的应用有哪些?
【10月更文挑战第16天】人工智能技术在金融领域的应用有哪些?
3901 1
|
12月前
|
监控 安全 搜索推荐
新手指南:Google邮箱注册全过程步骤教学
对于从事外贸、需要与外国客户或朋友沟通的小伙伴来说,拥有一个Google账号(也就是Gmail账号,下文统一用Google邮箱来表述)至关重要!
|
机器学习/深度学习 测试技术 计算机视觉
【计算机视觉 | ViT-G】谷歌大脑提出 ViT-G:缩放视觉 Transformer,高达 90.45% 准确率
谷歌大脑提出 ViT-G:缩放视觉 Transformer,高达 90.45% 准确率