Memory leaks 添加到UIWindow后如何销毁VC?

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") } } 现在在测试套件中,我可以创

对于某些类型的测试,我需要视图控制器位于UIWindow中。窗口本身从未显示。我在销毁视图控制器时遇到问题

说我们有

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
所做的那样),我尝试了,但没有成功。但是我没有在它之后添加运行循环泵,所以池可能没有被触发。让我再试一次并更新。我有同样的问题,它尝试了这个,似乎没有什么不同。