核心数据并发调试:误报

时间:2014-06-11 08:51:08

标签: ios multithreading core-data ios8

正如WWDC 2014 session 225(核心数据中的新增内容)中所述,iOS 8和OS X Yosemite上的核心数据现在支持命令行参数-com.apple.CoreData.ConcurrencyDebug 1,以启用检测违反Core Data并发性的断言合同。

在我的实验中,我发现它在iOS 8 beta 1下运行(在设备和模拟器中),但我似乎发现了误报,即框架抛出多线程违例异常不应该这样做的地方。至少这就是我所相信的。

问题:以下代码是正确的还是我做了违反Core Data线程模型的事情?

我所做的是设置一个非常简单的Core Data堆栈(带有内存存储,为简单起见),带有一个名为backgroundContext的托管对象上下文,具有私有队列并发性。然后我在该上下文中调用performBlockAndWait { },并在块中创建一个新的托管对象,将其插入上下文中,然后保存。

保存操作是我从Core Data获得多线程违例异常的地方。

var backgroundContext: NSManagedObjectContext?

func setupCoreDataStackAndViolateThreadingContract()
{
    let objectModelURL = NSBundle.mainBundle().URLForResource("CoreDataDebugging", withExtension: "momd")
    let objectModel: NSManagedObjectModel? = NSManagedObjectModel(contentsOfURL: objectModelURL)
    assert(objectModel)

    // Set up a simple in-memory Store (without error handling)
    let storeCoordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: objectModel)
    assert(storeCoordinator)
    let store: NSPersistentStore? = storeCoordinator!.addPersistentStoreWithType(NSInMemoryStoreType, configuration: nil, URL: nil, options: nil, error: nil)
    assert(store)

    // Set up a managed object context with private queue concurrency
    backgroundContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
    assert(backgroundContext)
    backgroundContext!.persistentStoreCoordinator = storeCoordinator!

    // Work on the background context by using performBlock:
    // This should work but throws a multithreading violation exception on 
    // self.backgroundContext!.save(&potentialSaveError)
    backgroundContext!.performBlockAndWait {
        NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: self.backgroundContext!) as NSManagedObject
        person.setValue("John Appleseed", forKey: "name")

        var potentialSaveError: NSError?
        // In the following line: EXC_BAD_INSTRUCTION in
        // `+[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__]:
        let didSave = self.backgroundContext!.save(&potentialSaveError)
        if (didSave) {
            println("Saving successful")
        } else {
            let saveError = potentialSaveError!
            println("Saving failed with error: \(saveError)")
        }
    }
}

我在Objective-C中测试了基本相同的代码并得到了相同的结果,所以我怀疑它是一个Swift问题。

编辑:如果您想自己运行代码,I have put a project on GitHub(需要Xcode 6 / iOS 8 beta)。

1 个答案:

答案 0 :(得分:1)

Apple确认这是一个错误。它已通过Xcode 6 beta 4修复。