id obj = [[NSObject alloc] init];
@autoreleasepool{
id __weak weakObj = obj;
_objc_autoreleasePoolPrint();
NSLog(@"%@",[weakObj class]);
_objc_autoreleasePoolPrint();
}运行上面的代码后,我在打印池时得到了意外的结果:
objc[22671]: [0x7ff544817858] ################ POOL 0x7ff544817858
objc[22671]: ##############我找不到在autoreleasepool中注册的对象。为什么?
发布于 2017-11-21 07:43:59
我想你误解了自动释放池是什么。它是一个对象集合,它将在池耗尽时(最常见的是在事件循环的末尾)接收release消息。它不是一个“以某种方式自动释放”的对象列表。它特别是将由该自动释放池发送release消息的对象(并且在任何给定时间可能有多个池)。
这和weak一点关系都没有。“弱”是一个变量(指针)的属性。"autoreleased“是发生在对象上的事情。对象可能会被自动释放多次(这是正常的)。
在手动内存管理中,这通常是通过向对象发送-autorelease来完成的。这意味着“现在不要释放它;我仍然需要它,但当当前的自动释放池耗尽时,释放它。”请注意,这并不意味着“销毁它”。它的意思就是“将保留计数减少1”。这就是你如何说“我只关心这个对象直到事件循环结束”(这是一个非常,非常常见的事情)。
在ARC中,你不能直接调用-autorelease,但在某些情况下,ARC仍然使用自动释放池。一种非常常见的方法是在返回之前对某件事调用objc_autoreleaseReturnValue()。(这不是你直接调用的东西。它是ARC在需要时自动注入的东西。)在某些情况下,objc_autoreleaseReturnValue()可能仍然不会将对象实际放到自动释放池中。编译器足够智能,可以检测到许多情况,在这些情况下,它可以避免池并提高性能。还有其他情况下,ARC可能会注入自动释放,这些情况也有优化,它可能会绕过池。
请注意,通常情况下,这是您的应用程序应该依赖的情况。_objc_autoreleasePoolPrint()是苹果内部的函数,用于低级调试。一些东西是否在自动释放池中,高度依赖于ARC实现细节和当前的编译器优化。
发布于 2017-11-21 07:19:20
obj永远不会自动释放,因此它不会放在自动释放池中。如果你想自动释放obj,你必须在它上面调用-autorelease,例如
@autoreleasepool {
id obj = [[[NSObject alloc] init] autorelease];
// ...
}请注意,-autorelease在ARC代码中不可用。
发布于 2017-11-22 10:50:43
我从这个link中得到了答案。
Apple LLVM version8.0.0 (clang-800.0.42.1)的__weak新实现并没有延迟到自动释放池,而是直接使用objc_release。
https://stackoverflow.com/questions/47388778
复制相似问题