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
中注册的对象。为什么?
最佳答案
我认为您误解了自动释放池是什么。它是一个对象集合,当池耗尽时(最常见的是在事件循环结束时),这些对象将收到 release
消息。它不是将“通过某种方式自动释放”的对象列表。 特别是将由该自动释放池(并且在任何给定时间可能有多个池)发送release
消息的对象。
它与 weak
没有任何关系。 “弱”是变量(指针)的一个属性。 “自动释放”是发生在对象 上的事情。对象可能会自动释放多次(这很正常)。
在手动内存管理中,这通常是通过向对象发送 -autorelease
来完成的。这意味着“不要现在释放它;我仍然需要它,但是当当前的自动释放池耗尽时,释放它。”请注意,这并不意味着“摧毁它”。它只是意味着“将保留计数减少一个”。这就是你所说的“我只关心这个对象直到事件循环结束”(这是一个非常非常想说的事情)。
在ARC中不能直接调用-autorelease
,但是ARC在某些情况下还是会使用autorelease pool。一种非常常见的方法是在返回某个对象之前调用 objc_autoreleaseReturnValue()
。 (这不是您直接调用的东西。它是 ARC 在需要时自动注入(inject)的东西。)在某些情况下,objc_autoreleaseReturnValue()
仍然可能实际上将对象放在自动释放上水池。编译器足够聪明,可以检测到许多可以避免池并提高性能的情况。在其他情况下,ARC 可能会注入(inject)自动释放,并且这些情况也有可能绕过池的优化。
请注意,在一般情况下,您的应用不应依赖此内容。 _objc_autoreleasePoolPrint()
是一个 Apple 内部函数,用于低级调试。某些东西是否在自动释放池中在很大程度上取决于 ARC 实现细节和当前的编译器优化。
关于ios - 为什么 __weak 变量没有在自动释放池中注册?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47388778/