[英]How to test deinit of viewController
我想測試是否刪除了視圖控制器deinit
的所有鍵值觀察器。
在測試類中,我定義了以下方法來啟動視圖控制器生命周期
func startLifecycle() {
_ = viewController.view
}
在我的測試方法中,我試圖通過簡單地將 nil 分配給我的視圖控制器實例來調用deinit
testViewController = nil
XCTAssert for stuff...
但是當我執行我的測試時沒有調用deinit
。 我在我的 VC 代碼中沒有看到明顯的保留周期,更重要的是,當我在我的應用程序中運行代碼時,而不是在測試環境中, deinit
因此它似乎沒有將視圖控制器保留在內存中。
測試時釋放視圖控制器的正確方法是什么?
我做了一個小測試。 當我使用標准的單視圖應用程序並將以下內容添加到ViewController時:
var value: Int? = 1
deinit {
value = nil
}
並運行以下測試:
func testExample() {
var viewController: ViewController? = ViewController()
XCTAssertEqual(viewController?.value, 1)
viewController = nil
}
deinit由測試執行(使用deinit中的斷點檢查)。
試試這樣
class ViewController: UIViewController {
var deinitCalled: (() -> Void)?
deinit { deinitCalled?() }
}
class ViewControllerTest: XCTestCase {
func test_deinit() {
var instance: ViewController? = ViewController()
let exp = expectation(description: "Viewcontroller has deinited")
instance?.deinitCalled = {
exp.fulfill()
}
DispatchQueue.global(qos: .background).async {
instance = nil
}
waitForExpectations(timeout: 2)
}
}
我有同樣的問題。
當您檢查內存圖時,您將看到UIStoryboardScene
類型的對象通過@autorelease
屬性“ sceneViewController
”維護對您的UIViewController
的引用。
如果您不熟悉 @autorelease,這是一篇有用的文章: https ://swiftrocks.com/autoreleasepool-in-2019-swift.html。 它解釋了使用 autorelease 創建的對象在當前線程的運行循環結束時被釋放,而不是在此之前。
在 Swift 中,我們可以使用autoreleasepool
來釋放UIStoryboardScene
對 UIViewController 的引用。
它可能看起來像這樣:
var testViewController: UIViewController?
autoreleasepool {
testViewController = UIStoryboard(name: "main", bundle: nil).instantiateInitialViewController()
}
然后,當您執行testViewController = nil
,UIViewController 實際上會取消初始化。
如果其他人需要這個,我設法這樣做。
// Given
var optionalSubject: UIViewController? = UIViewController()
// When
optionalSubject = nil // Call deinit
// Then
// TEST DEINIT
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.