首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Block中的auto 变量和static变量

  • 25-04-18 23:46
  • 3606
  • 9720
juejin.cn

自动变量,也就是局部变量,默认情况下在Objective-C中是存储在栈上的。它们的生命周期仅限于所在的作用域,比如函数或方法内部。当函数执行完毕,这些变量就会被释放。而静态变量是用static关键字声明的,它们的生命周期是整个程序运行期间,即使函数调用结束,静态变量的值也会保留下来,下次进入函数时还能继续使用。

接下来,用户可能需要了解这两种变量在Block中的捕获方式有什么不同。根据之前的回答,自动变量在Block中会被捕获为const,也就是说不能在Block内部修改,除非使用__block修饰符。而静态变量则可以直接在Block内部修改,因为Block捕获的是变量的地址,而不是值。

以下是 自动变量(auto变量)  和 静态变量(static变量)  的核心区别,结合代码说明它们的特性和在 Block 中的行为:


1. 本质区别

特性自动变量(auto变量)静态变量(static变量)
存储位置栈内存数据区(程序生命周期内存在)
生命周期函数/方法执行期间程序运行期间(即使函数退出也保留值)
初始化默认随机值(需手动初始化)默认初始化为0(或指定值)
Block捕获行为值捕获(需__block修饰才能修改)地址捕获(可直接修改)

2. 代码示例

示例 1:自动变量(auto变量)

scss
代码解读
复制代码
void testAutoVariable() { int autoVar = 10; // 自动变量(默认是auto,可省略) static int staticVar = 10; // 静态变量 void (^block)(void) = ^{ // autoVar = 20; // 编译错误:无法修改捕获的自动变量 staticVar = 20; // 允许修改静态变量 NSLog(@"autoVar = %d, staticVar = %d", autoVar, staticVar); }; autoVar = 30; // 修改自动变量的值(Block捕获的是autoVar的初始值) block(); NSLog(@"After block: staticVar = %d", staticVar); } // 调用函数 testAutoVariable();

输出结果:

ini
代码解读
复制代码
autoVar = 10, staticVar = 20 After block: staticVar = 20

关键解释:

  1. 自动变量 autoVar:

    • Block 捕获的是其初始值(autoVar = 10),且在 Block 内部不可直接修改。
    • 函数内修改 autoVar = 30 不影响 Block 捕获的值。
  2. 静态变量 staticVar:

    • Block 捕获的是变量地址,可直接修改。
    • 修改后的值在函数外仍保留(staticVar 变为 20)。

示例 2:使用 __block 修饰自动变量

objc

scss
代码解读
复制代码
void testBlockModifier() { __block int blockVar = 10; // 允许Block内修改 void (^block)(void) = ^{ blockVar = 50; // 直接修改 NSLog(@"blockVar = %d", blockVar); }; blockVar = 30; // 修改会影响Block内的值(因为Block持有引用) block(); } // 调用函数 testBlockModifier();

输出结果:

ini
代码解读
复制代码
blockVar = 50

关键解释:

  • __block 将自动变量移动到堆区,Block 持有其引用。
  • 函数内修改 blockVar = 30 会影响 Block 内的值(最终被 Block 修改为 50)。

3. 面试高频问题

Q:为什么静态变量不需要 __block 修饰就能在 Block 内修改?

  • 答案:Block 对静态变量捕获的是其内存地址(而非值拷贝),因此可以直接修改。静态变量的地址在程序运行期间固定。

Q:自动变量和静态变量的生命周期对 Block 有什么影响?

  • 答案:

    • 自动变量在函数退出后销毁,若 Block 被异步执行(如 GCD),访问已释放的自动变量会导致野指针。此时必须用 __block 或将其复制到堆区。
    • 静态变量始终存在,无需担心生命周期问题。

总结

场景自动变量静态变量
Block内修改需 __block 修饰直接修改
生命周期依赖依赖函数执行期间全局存在
内存管理栈内存(默认)或堆内存(__block)数据区(无需管理)

通过代码示例和对比,可以清晰理解两者在 Block 中的行为差异。

注:本文转载自juejin.cn的Lafar的文章"https://juejin.cn/post/7483764539952988187"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

141
iOS
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top