自动释放池何时在后台线程中释放对象?

dow*_*ang 3 nsautoreleasepool runloop ios

我知道当 runloop 处于 state 时,自动释放池会释放对象kCFRunLoopBeforeWaiting

所以我创建了一个后台线程,默认情况下 runloop 不运行。

如果我在这个后台线程中使用自动释放池,它什么时候释放对象。

Sol*_*ing 5

https://developer.apple.com/documentation/foundation/nsautoreleasepool?language=objc

自动释放池只是一个用于保存自动释放对象的无限堆栈。当您创建自动释放池时,池堆栈会推送观察者。当您对对象调用 autorelease 时,该对象将被推入池堆栈中。当你释放autorelease pool时,它会释放watcher之后所有推送的对象,然后删除watcher。

objc 中的 @autorelease 或 swift 中的 autorelease,只是创建自动释放池、调用块然后释放池的包装器。

runloop 会自动将任务包装到自动释放池中。

但是,当您将自动释放池与没有运行循环的自定义线程一起使用时,根据我的观察,对象将在线程退出时释放。

如何观察自动释放时间

您可以创建一个定义了 deinit 的自定义监视类,并手动保留和自动释放它,以观察 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")
Run Code Online (Sandbox Code Playgroud)

该脚本将打印

will exit pthread
a dealloced
finish
Run Code Online (Sandbox Code Playgroud)

你也可以在 deinit 处断点来查看 autorelease 的回溯