在 ARC 中使用 Blocks 和以某种方式复制的奇怪内存泄漏
Posted
技术标签:
【中文标题】在 ARC 中使用 Blocks 和以某种方式复制的奇怪内存泄漏【英文标题】:Weird memory leak with Blocks and copying in certain way in ARC 【发布时间】:2013-04-28 14:01:00 【问题描述】:以下简单代码在 ARC 下,在最新的 Xcode (4.6.2) 中使用 Leaks 工具进行分析,在 ios 模拟器中,在具有 -Os
优化的发布构建配置中显示泄漏:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
for (int i = 0; i < 10; i++)
void (^block)() = ^
NSLog(@"%d", i);
;
id x = block;
[x copy];
return YES;
它显示了 10 个泄露的块。 (它不会显示关闭优化的泄漏;但关闭优化对我们的应用程序来说是不现实的。)奇怪的是,查看每个泄漏块的内存管理历史记录,它们看起来都很好——每个都有一个 malloc从副本和发布;但不知何故释放不会释放它?
这是一个编译器错误(它使用的是默认的 Apple LLVM 编译器)吗?
【问题讨论】:
您确定 ARC 已开启吗?尝试插入-retain
看看编译器是否报错。
@KevinBallard:是的,ARC 已开启。如果 ARC 没有打开,为什么关闭优化后泄漏会消失?另外,如 Instruments 中所见,该块已释放;它只是没有被释放。
如果将id x = block; [x copy];
替换为[block copy]
会发生什么?
@Ríomhaire:它消失了。它必须是分配给id
的块类型,其他任何东西都不会重现它
【参考方案1】:
这似乎是编译器中的错误或泄漏工具,我不确定是哪个。您应该向 Apple 提交错误。
将代码缩短为以下代码时也会发生相同的泄漏:
int i = 0;
void (^block)() = ^
int y = i;
;
id x = block;
仅当块引用父作用域中的局部变量时才会出现泄漏。
您看到这种情况发生在实际生产代码中还是仅在本示例中?
【讨论】:
以上是关于在 ARC 中使用 Blocks 和以某种方式复制的奇怪内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章
带有块、ARC 和非 ARC 的 Objective C 内存管理
在 iOS 应用程序的生命周期中何时触发 ARC? [复制]