使用NSFileWrapper
和UIDocument
。文件写入发生在:
class MyDocument: UIDocument {
var wrapper: NSFileWrapper?
override internal func contentsForType(typeName: String) throws -> AnyObject {
// called by doc.saveToURL
if wrapper != nil {
// resaving an existing doc
}
else {
wrapper = NSFileWrapper.init(directoryWithFileWrappers: [:])
saveMyData()
}
return wrapper!
}
}
包装器在 saveMyData() 中修改。
似乎发生的情况是contentsForType
在单独的线程上运行,并且在极少数情况下会在 saveMyData 中修改包装器时运行,从而导致“集合在被枚举时发生变异”错误。
我已经阅读了有关 Objective-C 的其他线程@synchronized
,但 Swift 等价物仍然让我感到困惑。避免错误的最佳方法是什么?另外,测试错误的最佳方法是什么?它可能会发生 0.001 次,在用户同时更改数据时保存运行的奇怪情况下。
我读到的一种可能的解决方案是使用该defer
命令。以下列方式包含objc_sync_enter
和objc_sync_exit
在 saveMyData() 中是否有效?
func saveMyData() {
if wrapper == nil {
return
}
objc_sync_enter(wrapper)
defer { objc_sync_exit(wrapper) }
let data = NSKeyedArchiver.archivedDataWithRootObject(thumbnail)
if let wrap = wrapper!.fileWrappers!["thumbnail"] {
wrapper!.removeFileWrapper(wrap)
}
wrapper!.addRegularFileWithContents(data, preferredFilename: "thumbnail")
self.updateChangeCount(.Done)
}
不确定哪个线程最终等待另一个线程以及如何等待。
谢谢!