首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >弱视图引用在临时添加到视图层次结构后不会被释放

弱视图引用在临时添加到视图层次结构后不会被释放
EN

Stack Overflow用户
提问于 2022-03-12 03:56:45
回答 1查看 102关注 0票数 2

我碰到了最奇怪的事,也许有人有解释。步骤:

hierarchy

  • Remove
  1. 创建UIView A
  2. 创建对A
  3. 的弱引用,从视图层次结构
  4. Set A添加A到0

H 111弱引用仍然存在。H 212G 213/code>

如果您跳过步骤3和步骤4,弱引用将如预期的那样变为零。

测试代码:

TestView检查deinit

代码语言:javascript
复制
class TestView: UIView {
    deinit {
        print("deinit")
    }
}

单元测试

代码语言:javascript
复制
class RetainTests: XCTestCase {
    
    func testRetainFails() {
        let holderView = UIView()
        var element: TestView? = TestView()

        holderView.addSubview(element!)
        element?.removeFromSuperview()

        weak var weakElement = element
        XCTAssertNotNil(weakElement)
        // after next line `weakElement` should be nil
        element = nil
        // console will print "deinit"
        XCTAssertNil(weakElement) // fails!
    }

    func testRetainPasses() {
        var element: TestView? = TestView()

        weak var weakElement = element
        XCTAssertNotNil(weakElement)
        // after next line `weakElement` should be nil
        element = nil
        // console will print "deinit"
        XCTAssertNil(weakElement)
    }
}

这两个测试都会在控制台上打印出deinit,但在失败测试的情况下,如果element在视图层次结构中存在任何时间,则weakElement仍然保留引用,尽管element已成功地被解除分配。这怎么可能呢?

(编辑:这是一个应用程序,而不是游乐场)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-14 02:41:19

当您将TestView添加并移除到superview时,会有一个自动发布附加到它。如果确保耗尽自动释放池,则此测试的行为与您预期的一样:

代码语言:javascript
复制
autoreleasepool {
    holderView.addSubview(element!)
    element?.removeFromSuperview()
}

也就是说,你不能依赖这种行为。一个物体何时会被摧毁,这是没有承诺的。你只知道这是在你发布你最后一次强烈的参考之后。对象上可能有附加的保留或自动释放。也没有承诺deinit将永远被调用,所以一定要确保不将任何强制性的逻辑放在那里。它只应该执行内存清理。(出于稍微不同的原因,Mac和iOS都不会在程序终止期间调用deinit。)

在失败的测试用例中,deinit是在断言失败后打印的。您可以通过在失败的断言和print上放置断点来演示这一点。这是因为自动释放池在测试用例的末尾被耗尽。

底层的教训是,在传递给ObjC代码的对象上放置平衡的very /自动释放调用是非常常见的( UIKit是严重的ObjC)。通常不应该期望在当前事件循环结束之前销毁UIKit对象。不要依赖这个(这不是承诺),但这往往是真的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71446860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档