Swift Quick 框架内存泄漏

Posted

技术标签:

【中文标题】Swift Quick 框架内存泄漏【英文标题】:Swift Quick framework memory leak 【发布时间】:2020-05-16 11:01:45 【问题描述】:

我正在使用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())
            
        
    

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

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

【问题讨论】:

【参考方案1】:

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

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

class MyClass 
    deinit 
        print(self, #function)
    


final class MyClassTest: XCTestCase 
    let foo = MyClass()

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

deinit 未被调用为 foo

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

我相信这也直接转换为QuickSpec,所以我应该始终使用beforeEachafterEach 来管理对象。 为了“解决”这个问题,我应该像这样测试:

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

            beforeEach  foo = MyClass() 
            afterEach  foo = nil 

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

【讨论】:

我遇到了完全相同的问题,并且我无法在 Web 上找到许多与 Quick specs 中的内存管理相关的资源。我整理了一个非常简单的规范来测试这一点,我自己的发现似乎反映了你的。看起来该行为确实模仿了 XCTest 的行为。因此,除非其他人有比为每个分配实施 afterEach 更好的建议,否则我将继续这样做 ?

以上是关于Swift Quick 框架内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

Cocoa框架中是否存在内存泄漏?或者我错过了什么?

iOS swift 3中的内存泄漏

内存泄漏,在do-catch块中。 iOS,Swift

为啥在 swift 中创建字符串时会出现内存泄漏?

Swift 结构内存泄漏

使用HandyJSON导致的内存泄漏问题相关解决方法