iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0
自我挑戰組

自己的 Leak, 自己抓(swift)系列 第 28

概念驗證 Test Leak

  • 分享至 

  • xImage
  •  

之前有一陣子,有使用 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)
    }
}

上一篇
番外: Derived Path
下一篇
虛驚一場 Capture List
系列文
自己的 Leak, 自己抓(swift)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言