3li*_*3li 5 core-data ios swift
我试图了解Allows External Storage核心数据属性的行为,并看看它是否能让我免于手动在文件系统中存储文件。我想看看它在处理非常大的文件时表现如何。为此,我创建了一个虚拟项目并使用 Core Data 存储了一个大文件 (2 GB)。然后,我在获取和处理数据时监控了内存使用情况,令我惊讶的是,它没有超过 48 MB!这是为什么?它是否以块的形式获取数据?如果是这样,怎么办?该结构是否Data具有允许 Core Data 执行此操作的 API?
我所做的更多细节:
File创建一个只有两个属性的实体:(fileName字符串)和data(数据)。Allows External Storage属性的属性data。在实体中存储了 2 GB 文件File。我将此代码放入viewDidLoad方法中来执行此操作。
do {
// Store file
let fileURL = Bundle.main.url(forResource: "RawData/LargeFile", withExtension: nil)!
let file = File(context: AppDelegate.viewContext)
file.name = fileName
file.data = try Data(contentsOf: fileURL)
try AppDelegate.viewContext.save()
} catch {
print(error.localizedDescription)
}
Run Code Online (Sandbox Code Playgroud)关闭应用程序,然后使用新代码重新启动它,以viewDidLoad获取和处理大文件的数据。
let fileData = File.files(named: name).first!.data!
DispatchQueue.global(qos: .userInteractive).async {
let result = self.process(data: fileData)
print("The result: \(result)")
}
Run Code Online (Sandbox Code Playgroud)
filesFile 类的静态方法返回 File 实体中的所有文件。这里是 process 方法,它逐字节循环数据,读取和异或,然后返回结果。它实际上可以是任何方法,这里重要的是读取数据的所有字节。
private func process(data: Data) -> UInt8 {
print("Processsing \(data.count) bytes")
var accumulator: UInt8 = 0
for byte in data {
accumulator ^= byte
}
return accumulator
}
Run Code Online (Sandbox Code Playgroud)我监控了内存使用情况。
我很确定它与 Core Data 有关,而不是因为从磁盘 ( )Data加载时执行相同的步骤将导致 3+ GB 内存使用(另外,为什么要额外使用 1 GB?)。dataData(contentsOf: URL)
最后,是否有任何理由不使用该Allows External Storage功能,而是手动将文件存储在文件系统中?我知道这个问题已经被讨论过很多次了;但我读到的大多数建议使用手动方式的观点都提到了 Core Data 的性能问题,尽管我的小实验表明 Core Data 表现良好。
任何帮助,将不胜感激!
一般来说,关系数据库不擅长存储和检索大量数据。任何大于一兆字节的内容都不应该存储在数据库中。核心数据使问题变得更糟。如果您直接访问数据库,则只能获取特定的列,但是当核心数据将行转换为对象,将列转换为属性时,您无法控制所获取的内容。当您将属性设置为Allows External StorageCore-data 时,会将大量数据存储在文件系统中,并且仅在您访问该属性时加载它。这对于许多情况来说都很棒,因为它很简单并且可以极大地提高性能。
问题在于,访问此类属性可能会产生加载大文件的巨大意外成本,而仅访问属性并不清楚该成本。相反,如果您存储了文件名并明确执行了从磁盘加载文件的第二步,那么加载数据时就会很清楚。另外,如果可以从互联网恢复这些数据(例如,它们是从 imageURL 下载的图像),那么最好在核心数据之外管理该数据,因为您可以管理缓存,而这在核心数据中很难做到。
| 归档时间: |
|
| 查看次数: |
1898 次 |
| 最近记录: |