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

标签 ios objective-c nsautoreleasepool

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/

相关文章:

ios - 使用多点连接框架并保存发现的附近设备

objective-c - 将 char 转换为 NSString

ios - 如果当前的自动释放池被耗尽,是否会从内存中释放被触发的故障?

iPhone 自动释放池和分配

memory-management - 我是否通过显式处理 imageView.Image 来赢得内存?

ios - UICollectionView 没有出现在模拟器中

ios - 当涉及部分操作时,不调用 performBatchUpdates 完成处理程序

ios - 当应用程序处于终止状态时在 iOS 中接收推送通知

objective-c - iOS6 是否有任何严重的变更日志?

objective-c - 在 Mac 上获取 SHOUTcast 元数据