【问题标题】:When autorelease pool release object in background thread?当后台线程中的自动释放池释放对象时?
【发布时间】:2020-09-10 22:24:53
【问题描述】:

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

所以我创建了一个runloop默认不运行的后台线程。

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

【问题讨论】:

    标签: ios nsautoreleasepool runloop


    【解决方案1】:

    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 处断点来查看自动释放的回溯

    【讨论】:

    • 在您的观察中,当线程退出自定义线程时,对象将释放。你能告诉我如何验证它。
    • 1.创建线程。 2.使用dealloc定义创建一个自定义对象,并手动保留和自动释放它。 3.线程退出 4.检查自定义对象dealloc方法是否调用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 2023-03-09
    • 2016-08-31
    • 2011-11-19
    • 1970-01-01
    相关资源
    最近更新 更多