Swift 快速框架内存泄漏

Swift Quick framework memory leak

我正在使用 Quick 来测试我的 Swift 代码。 但是,我认为它不会释放 describe 范围内定义的对象:

class MyClass {
    deinit {
        print(self, #function)
    }
}

final class MyClassSpec: QuickSpec {
    override func spec() {
        describe("") {
            let foo = MyClass()
            it("") {
                print(foo)
                expect(true).to(beTrue())
            }
        }
    }
}

我没有看到 deinitprint 的任何输出,并且 deinit 中的调试断点没有被捕获。 如果我将 foo 移到 it 中,则会调用 deinit

这是 Quick 中的错误,还是 deinit 在测试套件中不被调用是正常的?

显然我写的代码不仅保留了对象,而且还是一个反模式。

即使是普通的旧 XCTestCase 也会保留一个对象:

class MyClass {
    deinit {
        print(self, #function)
    }
}

final class MyClassTest: XCTestCase {
    let foo = MyClass()

    func testMyClass() {
        print(foo)
        XCTAssert(true)
    }
}

deinit 未被调用 foo

这是由于XCTestCaseit never really gets deinited的性质。 因此,应该始终使用 setUptearDown 来管理 一切 (或更准确地说,具有引用语义的对象)。

我相信这也直接转化为 QuickSpec,所以我应该始终使用 beforeEachafterEach 来管理对象。 对于 "fix" 这个问题,我应该这样测试:

final class MyClassSpec: QuickSpec {
    override func spec() {
        describe("") {
            let foo: MyClass!

            beforeEach { foo = MyClass() }
            afterEach { foo = nil }

            it("") {
                print(foo)
                expect(true).to(beTrue())
            }
        }
    }
}