とを使用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 の同等物はまだ私を混乱させます。エラーを回避する最善の方法は何ですか? また、エラーをテストする最良の方法は何ですか? ユーザーが同時にデータを変更している間に保存が実行されるという奇妙な機会に、おそらく.001の確率で発生します。
私が読んだ考えられる解決策の1つは、defer
コマンドを使用することです。次のように saveMyData() に含めobjc_sync_enter
て動作しますか?objc_sync_exit
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)
}
どのスレッドが他のスレッドをどのように待機するのかが不明です。
ありがとうございました!