library(data.table)
DT <- fread("
3, 09/09/17 21:31:23, 09/09/17 21:31:23
3, 09/09/17 22:06:47, 09/09/17 22:06:47
3, 09/09/17 22:14:29, 09/09/17 22:18:17")
运行上面的代码后,打印池时出现意外结果:
id obj = [[NSObject alloc] init];
@autoreleasepool{
id __weak weakObj = obj;
_objc_autoreleasePoolPrint();
NSLog(@"%@",[weakObj class]);
_objc_autoreleasePoolPrint();
}
我找不到objc[22671]: [0x7ff544817858] ################ POOL 0x7ff544817858
objc[22671]: ##############
中注册的对象。为什么呢?
答案 0 :(得分:3)
我认为你误解了自动释放池是什么。它是一组对象,它们会在池耗尽时收到release
消息(最常见的是在事件循环结束时)。它不是“通过某种方式自动释放”的对象列表。 具体将通过此自动释放池发送release
消息的对象(并且在任何给定时间可能有多个池)。
它与weak
没有任何关系。 “weak”是变量(指针)的属性。 “自动释放”是对象发生的事情。对象可以多次自动释放(这是正常的)。
在手动内存管理中,通过向对象发送-autorelease
非常常见。这意味着“现在不要释放它;我仍然需要它,但是当当前自动释放池耗尽时,释放它。”请注意,这并不意味着“摧毁它”。它只是意味着“将保留计数减少一个”。这就是你怎么说“我只关心这个对象,直到事件循环结束”(这是一个非常非常常见的事情)。
在ARC中,您无法直接调用-autorelease
,但ARC在某些情况下仍会使用自动释放池。一种非常常见的方法是在返回之前调用objc_autoreleaseReturnValue()
。 (这不是你直接调用的东西。这是ARC在需要时自动注入的东西。)在某些情况下,objc_autoreleaseReturnValue()
仍然可能实际将对象放在自动释放池中。编译器非常智能,可以检测许多可以避免池并提高性能的情况。在其他情况下,ARC可能会注入自动释放,并且这些情况也可以在可能绕过池的情况下进行优化。
请注意,通常情况下,这是您的应用应该依赖的内容。 _objc_autoreleasePoolPrint()
是Apple内部函数,用于低级调试。是否存在自动释放池中的某些内容在很大程度上取决于ARC实现细节和当前编译器优化。
答案 1 :(得分:2)
obj
永远不会自动释放,因此它不会放在自动释放池中。如果您希望obj
自动释放,则必须在其上调用-autorelease
,例如
@autoreleasepool {
id obj = [[[NSObject alloc] init] autorelease];
// ...
}
请注意,-autorelease
在ARC代码中不可用。
答案 2 :(得分:0)
我从link获得答案。
Apple LLVM 8.0.0版本__weak(clang-800.0.42.1)的新版本不会将版本推迟到autoreleasepool,而是直接使用objc_release。