【问题标题】:Memory wont get cleared from background thread in SwiftSwift 中的后台线程不会清除内存
【发布时间】:2021-12-07 17:09:07
【问题描述】:

我有一个应用程序不断从我的服务器读取数据并更新 UI 中的数据。它会提取大量数据,构建一些数据结构,然后将信息传递给 UI。下面的代码显示了我是如何收集数据的:

class Server {
    private var units: [Unit] = []

    ...

    init {
        // I pull data from a firebase realtime database here using the observe method
        // which triggers the callback everytime the data changes
        // 'data' is a big dictionary of dictionarys  which will be sorted into objects
        FirebaseDatabaseHandler.getServerInfo(serverAddress: address, callback: { data in

            // Because its a lot of data sorting it is hefty so I do this on a background thread
            // 'updateQueue' is a single static DispatchQueue that I create in AppDelegate for now
            AppDelegate.updateQueue.async {

                // here I create an array of data objects using the JSON I pulled from firebase
                // then I set the "units" variable of this object and call my update callback
                // which triggers a UI update on the main thread
                if let unitData = (data?["units"] as? [String:Any]) {
                    var unitsArray = [Unit]()
            
                    for key in unitData.keys {
                        unitsArray.append(Unit(address: key.base64Decode, data: unitData[key] as! [String:Any]))
                    }
            
                    self.units = unitsArray
                    self.updateCallback()
                }
            } 
       })
   }
   
   ...

上面的代码运行良好,但是内存在不断地构建并且没有被适当地释放,在运行大约 10-20 分钟后,应用程序会构建高达 2GB 的内存并因内存不足而崩溃。

如果我摆脱 AppDelegate.updateQueue.async { } 并让这段代码在主线程上运行,内存确实会被清除并且没有崩溃,内存保持在 50-200mb 左右,但是如果我这样做,用户界面会由于主线程上发生了多少处理,基本上永久冻结

我尝试使用调试器查看我的units 数组和我的Server 对象的大小,但无论应用运行多长时间,大小都不会增长。

我可以做些什么来调试它,或者当我从后台线程运行它时内存不会被清除的任何原因?

【问题讨论】:

  • 您是否尝试过使用 Instruments 来调试应用程序的内存行为? (developer.apple.com/videos/play/wwdc2019/411)
  • 我尝试使用示例项目创建您的问题,在全局后台线程上运行,仍然得到解除分配,无法重现您的问题
  • @AchmadJP 我会看看我是否能想出一个简单的方法来重现......也许无论如何都会发现问题:P 感谢您的努力

标签: ios swift memory dispatch-queue


【解决方案1】:

添加[弱自我]:

FirebaseDatabaseHandler.getServerInfo(serverAddress: address, callback: {[weak self] data in

    AppDelegate.updateQueue.async { [weak self] in

请注意,您需要进行更多调整,因为 self 将变为可选。

【讨论】:

  • 刚试过这个,似乎仍然有同样的问题 - 将尝试创建一种简单的方法来重现它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-11
  • 2020-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多