考虑这个简单的Swift代码,它将设备运动数据记录到磁盘上的CSV文件中。
let motionManager = CMMotionManager()
var handle: NSFileHandle? = nil
override func viewDidLoad() {
super.viewDidLoad()
let documents = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
let file = documents.stringByAppendingPathComponent("/data.csv")
NSFileManager.defaultManager().createFileAtPath(file, contents: nil, attributes: nil)
handle = NSFileHandle(forUpdatingAtPath: file)
motionManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.currentQueue(), withHandler: {(data, error) in
let data_points = [data.timestamp, data.attitude.roll, data.attitude.pitch, data.attitude.yaw, data.userAcceleration.x,
data.userAcceleration.y, data.userAcceleration.z, data.rotationRate.x, data.rotationRate.y, data.rotationRate.z]
let line = ",".join(data_points.map { $0.description }) + "\n"
let encoded = line.dataUsingEncoding(NSUTF8StringEncoding)!
self.handle!.writeData(encoded)
})
}
我已经被困在这几天了。似乎存在内存泄漏,如内存 消费稳步增长,直到操作系统暂停应用程序超出资源。
这个应用程序能够长时间不间断地运行至关重要。一些说明:
startDeviceMotionUpdatesToQueue
中包装dispatch_async
)不会消除此问题NSOperationQueue
执行传感器数据处理可以解决问题(仅当maxConcurrentOperationCount
> = 2时)。但是,这会导致文件写入时出现并发问题:输出文件在相互交织的行之间出现乱码。任何指针?我曾尝试过使用乐器,但我不具备有效使用乐器的技能。爆炸式内存使用似乎是由__NSOperationInternal
引起的。这是一个示例Instruments trace。
谢谢。
答案 0 :(得分:2)
首先,看看我的这个答案:
https://stackoverflow.com/a/28566113/341994
您不应该在调试器中查看内存图;只相信乐器告诉你的东西。在Swift中,调试版本和发布版本的内存管理方式截然不同。
其次,如果仍有问题,请尝试将处理程序的内部包装在autoreleasepool
闭包中。我不认为这会产生影响,但是(因为这不是一个循环),我不认为它是必要的,因为我怀疑使用仪器将揭示首先从来没有任何问题。但是,autoreleasepool
调用将确保自动释放的对象没有机会累积。