测试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,编译器会为您维护它们。您的强引用和弱引用会变成对低级别系统保留、释放和自动释放函数的调用。(

我不确定它是否能在测试环境中工作,但你可能可以使用这样的代码:

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
}
}
}

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

该代码的问题在于,当执行对DispatchQueue.main.async()的调用时,测试可能已经结束。

编辑:

正如Cristik在评论中指出的那样,更好的方法是使用自动释放池命令:

func testReferences() throws {
//Define the vars we want to test outside of the auto-release pool statement.
weak var weakVC: UIViewController
weak var weakNC: UINavigationController
autoreleasepool {
var strongVC: UIViewController? = UIViewController()
var strongNC: UINavigationController? = UINavigationController(rootViewController: strongVC!)
weakVC = strongVC
weakNC = strongNC
strongVC = nil

XCTAssertNotNil(weakVC)
XCTAssertNotNil(weakNC)

strongNC = nil
}
//Test for nil outside of the autorelasepool statement, 
//after the auto-release pool is drained.
XCTAssertNil(weakVC) // fails
XCTAssertNil(weakNC) // fails
}

相关内容

  • 没有找到相关文章

最新更新