【发布时间】:2020-09-10 22:24:53
【问题描述】:
我知道当runloop处于kCFRunLoopBeforeWaiting状态时,自动释放池会释放对象。
所以我创建了一个runloop默认不运行的后台线程。
如果我在这个后台线程中使用自动释放池,它什么时候释放对象。
【问题讨论】:
标签: ios nsautoreleasepool runloop
我知道当runloop处于kCFRunLoopBeforeWaiting状态时,自动释放池会释放对象。
所以我创建了一个runloop默认不运行的后台线程。
如果我在这个后台线程中使用自动释放池,它什么时候释放对象。
【问题讨论】:
标签: ios nsautoreleasepool runloop
https://developer.apple.com/documentation/foundation/nsautoreleasepool?language=objc
自动释放池只是用于保存自动释放对象的无限堆栈。 当您创建自动释放池时,池堆栈会推送一个观察者。 当您在对象上调用 autorelease 时,该对象被推入池堆栈。 当你释放自动释放池时,它会在观察者之后释放所有推送的对象,然后删除观察者。
objc 中的@autorelease 或swift 中的autorelease,只是一个用于创建自动释放池、调用块然后释放池的包装器。
runloop 会自动将任务包装到自动释放池中。
但是当您将自动释放池与没有运行循环的自定义线程一起使用时,根据我的观察,对象将在线程退出时释放..
您可以创建一个定义了 deinit 的自定义 watch 类,并手动保留和自动释放它,以观察 deinit 时间。代码如下
class A {
deinit {
print("a dealloced")
}
}
var p: pthread_t?
_ = pthread_create(&p, nil, { (p) -> UnsafeMutableRawPointer? in
do {
let a = A()
_ = Unmanaged.passRetained(a).autorelease()
}
print("will exit pthread")
return nil
}, nil)
pthread_join(p!, nil)
print("finish")
这个脚本会打印出来
will exit pthread
a dealloced
finish
你也可以在 deinit 处断点来查看自动释放的回溯
【讨论】: