2

使用NSFileWrapperUIDocument。文件写入发生在:

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_enterobjc_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)
}

不确定哪个线程最终等待另一个线程以及如何等待。

谢谢!

4

0 回答 0