首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么自动释放池中没有注册__weak变量?

为什么自动释放池中没有注册__weak变量?
EN

Stack Overflow用户
提问于 2017-11-20 17:32:28
回答 3查看 162关注 0票数 0
代码语言:javascript
复制
id obj = [[NSObject alloc] init];
@autoreleasepool{
    id __weak weakObj = obj;
    _objc_autoreleasePoolPrint();
    NSLog(@"%@",[weakObj class]);
    _objc_autoreleasePoolPrint();
}

运行上面的代码后,我在打印池时得到了意外的结果:

代码语言:javascript
复制
objc[22671]: [0x7ff544817858]  ################  POOL 0x7ff544817858
objc[22671]: ##############

我找不到在autoreleasepool中注册的对象。为什么?

EN

回答 3

Stack Overflow用户

发布于 2017-11-21 07:43:59

我想你误解了自动释放池是什么。它是一个对象集合,它将在池耗尽时(最常见的是在事件循环的末尾)接收release消息。它不是一个“以某种方式自动释放”的对象列表。它特别是将由该自动释放池发送release消息的对象(并且在任何给定时间可能有多个池)。

这和weak一点关系都没有。“弱”是一个变量(指针)的属性。"autoreleased“是发生在对象上的事情。对象可能会被自动释放多次(这是正常的)。

在手动内存管理中,这通常是通过向对象发送-autorelease来完成的。这意味着“现在不要释放它;我仍然需要它,但当当前的自动释放池耗尽时,释放它。”请注意,这并不意味着“销毁它”。它的意思就是“将保留计数减少1”。这就是你如何说“我只关心这个对象直到事件循环结束”(这是一个非常,非常常见的事情)。

在ARC中,你不能直接调用-autorelease,但在某些情况下,ARC仍然使用自动释放池。一种非常常见的方法是在返回之前对某件事调用objc_autoreleaseReturnValue()。(这不是你直接调用的东西。它是ARC在需要时自动注入的东西。)在某些情况下,objc_autoreleaseReturnValue()可能仍然不会将对象实际放到自动释放池中。编译器足够智能,可以检测到许多情况,在这些情况下,它可以避免池并提高性能。还有其他情况下,ARC可能会注入自动释放,这些情况也有优化,它可能会绕过池。

请注意,通常情况下,这是您的应用程序应该依赖的情况。_objc_autoreleasePoolPrint()是苹果内部的函数,用于低级调试。一些东西是否在自动释放池中,高度依赖于ARC实现细节和当前的编译器优化。

票数 3
EN

Stack Overflow用户

发布于 2017-11-21 07:19:20

obj永远不会自动释放,因此它不会放在自动释放池中。如果你想自动释放obj,你必须在它上面调用-autorelease,例如

代码语言:javascript
复制
@autoreleasepool {
    id obj = [[[NSObject alloc] init] autorelease];
    // ...
}

请注意,-autorelease在ARC代码中不可用。

票数 2
EN

Stack Overflow用户

发布于 2017-11-22 10:50:43

我从这个link中得到了答案。

Apple LLVM version8.0.0 (clang-800.0.42.1)的__weak新实现并没有延迟到自动释放池,而是直接使用objc_release。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47388778

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档