Memory leaks 添加到UIWindow后如何销毁VC?
对于某些类型的测试,我需要视图控制器位于UIWindow中。窗口本身从未显示。我在销毁视图控制器时遇到问题 说我们有Memory leaks 添加到UIWindow后如何销毁VC?,memory-leaks,uiviewcontroller,xctest,uiwindow,Memory Leaks,Uiviewcontroller,Xctest,Uiwindow,对于某些类型的测试,我需要视图控制器位于UIWindow中。窗口本身从未显示。我在销毁视图控制器时遇到问题 说我们有 class MyViewController: UIViewController { deinit { print("MyVC bye-bye") } } class MyWindow: UIWindow { deinit { print("MyWindow bye-bye") } } 现在在测试套件中,我可以创
class MyViewController: UIViewController {
deinit {
print("MyVC bye-bye")
}
}
class MyWindow: UIWindow {
deinit {
print("MyWindow bye-bye")
}
}
现在在测试套件中,我可以创建这两个对象,它们将被释放
class MyTests: XCTestCase {
func test() {
let vc = MyViewController()
let window = MyWindow()
}
}
在控制台输出中,我看到
MyWindow bye-bye
MyVC bye-bye
但如果我在测试中添加以下行,则两个对象都不会被破坏
window.addSubview(vc.view)
稍后自动释放池可能会清理窗口本身。但是我主要担心的是视图控制器没有被破坏
window.addSubview(vc.view)
我试过了
vc.view.removeFromSuperview()
但这还不够。泵送运行循环会给自动释放池一个提示,这样在测试结束后就不会有对象逗留。如果对象纯粹是测试的本地对象,请将对象放置在自动释放池中并执行以下操作:
func test() {
autoreleasepool {
let vc = MyViewController()
let window = MyWindow()
window.addSubview(vc.view)
}
RunLoop.current.run(until: Date())
}
但是在大多数测试套件中,视图控制器是测试夹具的一部分。在这种情况下,释放夹具后泵送回路
override func tearDown() {
vc = nil
RunLoop.current.run(until: Date())
super.tearDown()
}
泵送运行循环会给自动释放池一个提示,这样在测试结束后就不会有对象逗留。如果对象纯粹是测试的本地对象,请将对象放置在自动释放池中并执行以下操作:
func test() {
autoreleasepool {
let vc = MyViewController()
let window = MyWindow()
window.addSubview(vc.view)
}
RunLoop.current.run(until: Date())
}
但是在大多数测试套件中,视图控制器是测试夹具的一部分。在这种情况下,释放夹具后泵送回路
override func tearDown() {
vc = nil
RunLoop.current.run(until: Date())
super.tearDown()
}
如果我在一个全新的Xcode项目(使用单视图应用程序模板)中创建这个场景,我会看到日志输出,表明窗口和视图控制器都按预期解除分配。也许你的项目配置有什么特别的地方?啊,我没有检查完整的日志。结果证明我们都是对的。它正在被解除分配,但只有在测试运行程序完全关闭之后。因此,这给了我一个线索,这导致了一个答案…如果我在一个全新的Xcode项目中创建这个场景(使用单视图应用程序模板),我会看到日志输出,表明窗口和视图控制器都得到了预期的释放。也许你的项目配置有什么特别的地方?啊,我没有检查完整的日志。结果证明我们都是对的。它正在被解除分配,但只有在测试运行程序完全关闭之后。因此,这给了我一个线索,这导致了一个答案…将特定的测试用例体包装在
autoreleasepool
中不也会起作用吗?这不会影响所有剩余的测试用例(正如tearDown
所做的那样),我尝试了,但没有成功。但是我没有在它之后添加运行循环泵,所以池可能没有被触发。让我再试一次并更新。我也遇到了同样的问题,它尝试了这个,但似乎没有什么不同。在autoreleasepool
中包装特定的测试用例主体是否也能正常工作?这不会影响所有剩余的测试用例(正如tearDown
所做的那样),我尝试了,但没有成功。但是我没有在它之后添加运行循环泵,所以池可能没有被触发。让我再试一次并更新。我有同样的问题,它尝试了这个,似乎没有什么不同。