【问题标题】:Storing and working with huge dictionaries in Swift在 Swift 中存储和使用庞大的字典
【发布时间】:2017-06-08 21:16:48
【问题描述】:

我正在尝试将包含大约 11,000 对的字典加载到 Swift 程序中(大约 0.7MB)。字典的值是数组,我需要能够遍历字典的数组并将这些值与另一个数组中的值进行比较。子数组中平均有 10 个项目,虽然有的有两个或三个,有的有数百个。

程序崩溃了,我正在寻找一种方法来修复它,同时保留我基于 Python 原型的功能。我在考虑使用一堆属性列表,并将它们一个一个加载到内存中,但这似乎效率低下。我可以做些什么来重新设计它?

部分有问题的代码:var dictOfHashesAndMaterials:[String:[Int]]: = ["10928123sdfb234w3fw3": [123,435,1,573,456,3234,653,57856,434,345],"13435fw323df0239dfsdf":[435,756,978,231,5668,485,9678,1233,87,989]] // and 11,000 additional entries which look similar to this.

这就是我使用它的地方:` // 填充成分列表的函数。 func populateListOfRecipes(){ var storedIngredients = UserDefaults.standard.object(forKey: "ingredients") as! [整数]

    for(key, value) in dictOfHashesAndMaterials{
        let listSet = Set(storedMaterials)
        let findListSet = Set(value)
        if findListSet.isSubset(of: listSet){
            print("found a match!")
            arrayOfAvailableProjects.append(key)
        }
    }

    tableView.reloadData()

}`

tableView 然后由链接到给定项目细节的单元格填充。将哈希发送到服务器时填写详细信息,并将相应的指令完整返回给应用程序。

【问题讨论】:

  • 你能更好地描述崩溃吗?
  • 初始化文字时,Xcode 和模拟器都冻结了,并且报告指出进程在几分钟内没有响应。当我检查崩溃报告时,我看到正在创建的字典对象占用了大约 350mb 的内存空间。我的假设是该对象是如此之大,并且对该对象的调用如此频繁以至于机器无法处理它。澄清一下,将字典复制/粘贴到文本文件中是 0.7 兆。实际的对象可能要大得多。
  • 您需要显示一些代码,但请注意 Swift 字典是在修改时复制的结构,因此每次修改字典时都会创建一个新副本。如果您在循环中执行此操作,则 arc 将没有机会清理过时的副本。使用 NSMutableDictionary 或修改“加载”代码可能会更好。你能显示一些代码吗?
  • 我会在原帖中添加一些代码。它不会让我在 cmets 中做得很好。
  • 尝试将 for 循环的内容放在 autoreleasepool 块中,但听起来它甚至没有那么远;它正在初始化问题所在的文字。您也可以使用 Instruments 来分析内存使用情况,但您可能会发现从 plist 等外部源加载数据比使用大字面量更好。此外,如果字典从未发生变异,请使用 let 而不是 var

标签: ios swift dictionary


【解决方案1】:

它在模拟器中崩溃了吗?我使用模拟器处理了 30 GB 的文件而没有崩溃。在设备上是不同的故事......

不管怎样,试试这个:

for(key, value) in dictOfHashesAndMaterials{
     autoreleasepool {
        let listSet = Set(storedMaterials)
        let findListSet = Set(value)
        if findListSet.isSubset(of: listSet){
            print("found a match!")
            arrayOfAvailableProjects.append(key)
        }
    }
}

tableView.reloadData()

}

通过在每次迭代时清空自动释放池,您可以防止可用内存不足。

【讨论】:

  • 如 Paulw11 所建议的那样,它是否有所作为,或者问题是否发生在您进入此循环之前?
猜你喜欢
  • 2019-03-09
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 1970-01-01
  • 2011-04-10
  • 1970-01-01
  • 1970-01-01
  • 2013-07-14
相关资源
最近更新 更多