最近,我试图使用单元测试来验证我编写的对象是否正确解除分配。然而,我发现无论我尝试什么,对象都不会在测试完成之前解除分配。所以我将测试简化为一个简单的例子(见下文),它试图证明使用弱变量的对象释放的基础知识。

在我看来,强引用应该在测试方法退出后停止保留对象,而弱引用在下一个运行循环中被引用时应该为零。但是,弱引用永远不会为零,并且两个测试都失败了。我在这里误解了什么吗?以下是完整的单元测试。

class Mock { //class type, should behave with reference semantics

    init() { }
}

class DeallocationTests: XCTestCase {

    func testWeakVarDeallocation() {

        let strongMock = Mock()

        weak var weakMock: Mock? = strongMock

        let expt = expectation(description: "deallocated")

        DispatchQueue.main.async {

            XCTAssertNil(weakMock)      //This assertion fails

            expt.fulfill()
        }

        waitForExpectations(timeout: 1.0, handler: nil)
    }

    func testCaptureListDeallocation() {

        let strongMock = Mock()

        let expt = expectation(description: "deallocated")

        DispatchQueue.main.async { [weak weakMock = strongMock] in

            XCTAssertNil(weakMock)      //This assertion also fails

            expt.fulfill()
        }

        waitForExpectations(timeout: 1.0, handler: nil)
    }
}

我认为 XCTest 可能以某种方式推迟了解除分配,但即使将测试方法主体包装在 autoreleasepool 中也不会导致对象解除分配。

最佳答案

问题是当 testWeakVarDeallocation() 块被调用时,你的 dispatchAsync 函数没有退出,所以对 strongMock 的强引用仍然存在。

像这样尝试(允许 testWeakVarDeallocation() 退出),你会看到 weakMock 变成了预期的 nil:

class weakTestTests: XCTestCase {
    var strongMock: Mock? = Mock()

    func testWeakVarDeallocation() {
        weak var weakMock = strongMock

        print("weakMock is \(weakMock)")

        let expt = self.expectation(description: "deallocated")

        strongMock = nil

        print("weakMock is now \(weakMock)")

        DispatchQueue.main.async {
            XCTAssertNil(weakMock)      // This assertion fails

            print("fulfilling expectation")
            expt.fulfill()
        }

        print("waiting for expectation")
        self.waitForExpectations(timeout: 1.0, handler: nil)
        print("expectation fulfilled")
    }
}

关于Swift XCTest : Verify proper deallocation of weak variables,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41308381/

10-12 17:48