首页 > 解决方案 > 在 Swift 中使用线程会导致内存泄漏

问题描述

在我的 ViewModel 中使用线程时,我在我的应用程序中遇到了一个奇怪的行为。似乎 Thread.init 中发生了一些事情,即使调用 Thread 对象的 deinit(我什至没有启动线程)也会导致内存泄漏。

我对 Swift 比较陌生,所以这可能是我的错,但我不知道为什么。我有两个通过 NavigationView 链接在一起的视图。子 View 有一个 ViewModel,它在调用初始化方法时创建一个 Thread 并在调用反初始化方法时销毁 Thread 对象。当子 View “关闭”时,会调用 ViewModel 的去初始化方法。导航回父视图后,我可以在 Xcode 的内存分析器中看到新的内存泄漏

在此处输入图像描述

我在下面发布了一个重现此问题的小示例

HomeView:(主视图)

import SwiftUI

struct HomeView: View {
    @State private var showView = false
    
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: TestView(showView: self.$showView), isActive : self.$showView) {
                    Text("Open MainView")
                }.isDetailLink(false)
                .navigationBarTitle("Home")
            }
        }
    }
}

TestView:(子视图)

import SwiftUI

struct TestView: View {
    
    @Binding var showView : Bool
    
    @StateObject var mainViewModel = TestViewViewModel()
    
    var body: some View {
        Button("Back") {
            showView = false
        }.onAppear(perform: {
            mainViewModel.initViewModel()
        })
        .onDisappear(perform: {
            mainViewModel.deinitViewModel()
        })
    }
}

视图模型:

import Foundation

class TestViewViewModel: ObservableObject {
    
    private var testThread: TestThread?
    
    public func initViewModel() {
        testThread = TestThread.init()
    }
    
    public func deinitViewModel() {
        testThread?.cancel()
        testThread = nil
    }
    
    
    /*+++++++++++++++*/
    /*+ Test thread +*/
    /*+++++++++++++++*/

    private class TestThread: Thread {

        override init(){
            print("Init RenderThread")
        }
        
        deinit {
            print("deinit RenderThread")
        }

        override func main() {
            
        }
    }
}

就是这样,不涉及任何魔法,但是当单击子视图中的“后退”按钮时,似乎不会在 ViewModel 的线程中被垃圾收集。任何提示可能有什么问题?这是一个错误还是我必须手动发布一些东西?

标签: iosswiftmemory-leaksswift5xcode12.5

解决方案


推荐阅读