微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

测试UINavigationController释放失败?

如何解决测试UINavigationController释放失败?

我有以下单元测试:

func testReferences() throws {
        var strongVC: UIViewController? = UIViewController()
        var strongNC: UINavigationController? = UINavigationController(rootViewController: strongVC!)
        weak var weakVC = strongVC
        weak var weakNC = strongNC
        strongVC = nil
        
        XCTAssertNotNil(weakVC)
        XCTAssertNotNil(weakNC)
        
        strongNC = nil
        
        XCTAssertNil(weakVC) // fails
        XCTAssertNil(weakNC) // fails
    }

最后两个断言失败。有什么方法可以可靠地测试UIViewController和UINavigationController的释放吗?

解决方法

我记得,文档中说持有不充分的对象“ 可以随时释放”。执行部分是“可能是”。

我猜测您的视图控制器和导航控制器已自动释放。这个术语可以追溯到手动引用计数的日子,但在掩盖下仍然有意义。创建的对象的保留计数为1,然后将其添加到“自动释放池”中。然后,下次您的应用程序的当前函数返回并访问事件循环时,“自动释放池已耗尽”,这意味着自动释放池中的每个条目都会收到释放消息,将其保留计数降低1。保留计数降至零,对象将被释放。

(ARC实际上是在后台使用引用计数,因此保留计数和自动释放池仍然很重要。只是使用ARC,编译器会为您维护它们。您的强引用和弱引用都变成了调用低级系统会保留,释放和自动释放功能。)

我不确定它是否可以在测试环境中使用,但是您可能可以使用如下代码:

SELECT TOP 0 * INTO #temp FROM Active

DELETE FROM Active
OUTPUT DELETED.* INTO #temp
WHERE Id IN (...)

MERGE INTO Archive 
USING #temp AS Active
ON (Active.Id = Archive.Id)
WHEN NOT MATCHED THEN
INSERT (Id,...)
VALUES (Active.Id,...);

该代码将导致对SubjectAlternativeNames的调用被推迟到下一次通过事件循环为止。

该代码的问题在于,到执行func testReferences() throws { var strongVC: UIViewController? = UIViewController() var strongNC: UINavigationController? = UINavigationController(rootViewController: strongVC!) weak var weakVC = strongVC weak var weakNC = strongNC strongVC = nil XCTAssertNotNil(weakVC) XCTAssertNotNil(weakNC) strongNC = nil DispatchQueue.main.async { XCTAssertNil(weakVC) // fails XCTAssertNil(weakNC) // fails } } } 的调用时,测试可能已经结束。

编辑:

正如Cristik在其评论中指出的那样,更好的方法是使用autoreleasepool命令:

XCTAssertNil()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。