如何解决测试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 举报,一经查实,本站将立刻删除。