在应用程序文本日志记录中持久(不在内存中)的最有效方法/策略是什么?



我有一个导航和位置跟踪应用程序。当用户跟踪他的行程时,坐标、速度、时间戳(以及更多)会记录每个输入的坐标。我不想将其存储在内存中,因为这会使应用程序内存随着用户的移动而增长,最终导致didReceiveMemoryWarning甚至应用程序崩溃。(至少这是我迄今为止的经验)

最有效的方法是什么?考虑电池消耗,CPU使用率以及内存使用率(如果这发挥作用)。

我可以想到两种选择:

  1. 登录一个文件(我目前正在做什么,使用截取的这段代码):
let newLine: String = "bla bla bla"
let url: URL = URL(string: "someLocalPath")
newLine.appendToURL(url)
extension String {
func appendToURL(_ fileURL: URL) throws {
let data = self.data(using: String.Encoding.utf8)!
try data.appendToURL(fileURL)
}
}
extension Data {
func appendToURL(_ fileURL: URL) throws {
if let fileHandle = try? FileHandle(forWritingTo: fileURL) {
defer {
fileHandle.closeFile()
}
fileHandle.seekToEndOfFile()
fileHandle.write(self)
fileHandle.closeFile()
}
else {
try write(to: fileURL, options: .atomic)
}
}
}
  1. 使用核心数据

    我还没有尝试过这个,但我相信它会相对容易。只需创建一个包含所有必需字段的实体,然后为每个收到的坐标添加一个managedObject

所以,重复我的问题:从电池、CPU 和内存的角度来看,这两个选项中哪一个更有效率?

附加问题:是否有另一种方法可以做到这一点。一个我没有想到的?

我找到了另一个最适合我的选择。首先🤦🏻 ♂️应该想到这一点.

所以,我不想登录到内存,因为它可能会使iOS由于内存使用过多而杀死我的应用程序。但是,iOS 首先发送一个didReceiveMemoryWarning,您可以在该上减少应用程序的内存占用,防止它被杀死。

所以,我现在要做的是:

我添加了一个实例变量:

fileprivate var logString: String = ""

并在收到新坐标时记录到它:

logString += newLine

如果我/当我得到一个didReceiveMemoryWarning我将整个logString写入磁盘上的文件,然后清空它:

override func didReceiveMemoryWarning() {
logString.appendToURL(url)
logString = ""
}

这样,我只在必要时写入磁盘(而不是接收到每个坐标),这更加节能。(写入磁盘比写入内存消耗更多的能量。资料来源:https://developer.apple.com/videos/play/wwdc2016/719/)

另外,由于内存使用率高,我的应用程序不会被 iOS 杀死,因为我会及时清理内存。

最新更新