gpt4 book ai didi

objective-c - 递归 block 保留循环

转载 作者:太空狗 更新时间:2023-10-30 03:13:21 24 4
gpt4 key购买 nike

这会导致任何形式的保留周期吗?使用安全吗?

__block void (^myBlock)(int) = [^void (int i)
{
if (i == 0)
return;

NSLog(@"%d", i);
myBlock(i - 1);
} copy];
myBlock(10);

myBlock = nil;

最佳答案

您的代码确实包含一个保留循环,但您可以通过在递归基本情况下将 myBlock 设置为 nil 来在递归结束时中断保留循环(我 == 0)。

证明这一点的最好方法是尝试一下,在分配工具下运行,关闭“停止时丢弃未记录的数据”,打开“记录引用计数”,并关闭“仅跟踪事件分配”。

我使用 OS X 命令行工具模板创建了一个新的 Xcode 项目。这是整个程序:

#import <Foundation/Foundation.h>

void test() {
__block void (^myBlock)(int) = [^void (int i){
if (i == 0) {
// myBlock = nil;
return;
}
NSLog(@"myBlock=%p %d", myBlock, i);
myBlock(i - 1);
} copy];
myBlock(10);
}

int main(int argc, const char * argv[])
{
@autoreleasepool {
test();
}
sleep(1);
return 0;
}

然后我使用上面描述的设置在 Allocations 工具下运行它。然后我在 Instruments 中将“Statistics”更改为“Console”,以查看程序输出:

2012-10-26 12:04:31.391 recursiveBlockTest[71789:303] myBlock=0x7ff142c24700 10
2012-10-26 12:04:31.395 recursiveBlockTest[71789:303] myBlock=0x7ff142c24700 9
2012-10-26 12:04:31.396 recursiveBlockTest[71789:303] myBlock=0x7ff142c24700 8
2012-10-26 12:04:31.397 recursiveBlockTest[71789:303] myBlock=0x7ff142c24700 7
2012-10-26 12:04:31.397 recursiveBlockTest[71789:303] myBlock=0x7ff142c24700 6
2012-10-26 12:04:31.398 recursiveBlockTest[71789:303] myBlock=0x7ff142c24700 5
2012-10-26 12:04:31.398 recursiveBlockTest[71789:303] myBlock=0x7ff142c24700 4
2012-10-26 12:04:31.399 recursiveBlockTest[71789:303] myBlock=0x7ff142c24700 3
2012-10-26 12:04:31.400 recursiveBlockTest[71789:303] myBlock=0x7ff142c24700 2
2012-10-26 12:04:31.401 recursiveBlockTest[71789:303] myBlock=0x7ff142c24700 1
<End of Run>

我复制了 block 地址(0x7ff142c24700),将“控制台”更改为“对象列表”,并将地址粘贴到搜索框中。 Instruments 只向我展示了 block 的分配:

block leaked

Live 列下的点表示程序退出时该 block 仍在分配。它被泄露了。我单击地址旁边的箭头以查看 block 分配的完整历史记录:

block leaked detail

这个分配只发生了一件事:它被分配了。

接下来我取消注释 if (i == 0) 语句中的 myBlock = nil 行。然后我再次在分析器下运行它。为了安全起见,系统随机分配内存地址,因此我清除了搜索栏,然后再次检查控制台以获取此次运行中的 block 地址。这次是 0x7fc7a1424700。我再次切换到“对象列表” View 并粘贴新地址 0x7fc7a1424700。这是我看到的:

block freed

这次 Live 栏下没有点,这意味着程序退出时该 block 已被释放。然后我单击地址旁边的箭头以查看完整的历史记录:

block freed detail

这一次, block 被分配、释放和释放。

关于objective-c - 递归 block 保留循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13090598/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com