之前有一陣子,有使用 test 來驗證 leak 的文章出沒
這種用 test 來找 leak 的方式
以個人的想法來說,還不如直接使用 Xcode Instruments
test leak 屬於 runtime 的行為
也就當沒有執行到特定段落的情況
是沒有 leak 的狀態發生
因此必須準備更多的情境
越多的情境,進一步導致測試成本會提高(偏向整合測試)
個人的想法還是偏向用 test leak 去做概念驗證,以及協助理解 swift capture 等機至
並且去理解某一種 code pattern 會導致 leak 發生
如下:
import Foundation
import XCTest
private class Concept {
typealias Callback = () -> Concept?
private var cb: Callback?
private var nest: Callback?
func leak() -> Concept? {
cb = { // [self]
let nest = { [weak self] in
self
}
return nest()
}
return cb?()
}
func noleak() -> Concept? {
cb = { [weak self] in
self?.nest = { [weak self] in
self
}
return self?.nest?()
}
return cb?()
}
func captureWeak() -> Concept? {
cb = { [weak self] in
self?.nest = {
self
}
return self?.nest?()
}
return cb?()
}
func captureStrong() -> Concept? {
cb = { [weak self] in
let `self`: Concept? = self
self?.nest = {
self
}
return self?.nest?()
}
return cb?()
}
}
final class ConcepctTests: XCTestCase {
private var concept: Concept? = nil
private weak var _concept: Concept? = nil
override func setUp() {
super.setUp()
concept = Concept()
_concept = concept
}
override func tearDown() {
concept = nil
_concept = nil
super.tearDown()
}
func testConceptNestedSpecial_noleak() {
XCTAssertNotNil(concept?.noleak())
XCTAssertNotNil(_concept)
concept = nil
XCTAssertNil(_concept)
}
func testConceptNestedSpecial_leak() {
XCTAssertNotNil(concept?.leak())
XCTAssertNotNil(_concept)
concept = nil
XCTAssertNotNil(_concept)
}
func testConceptNestedCaptureWeak() {
XCTAssertNotNil(concept?.captureWeak())
XCTAssertNotNil(_concept)
concept = nil
XCTAssertNil(_concept)
}
func testConceptNestedCaptureStrong() {
XCTAssertNotNil(concept?.captureStrong())
XCTAssertNotNil(_concept)
concept = nil
XCTAssertNotNil(_concept)
}
}