2014-06-11 54 views
10

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

在我的实验中,我发现它可以在iOS 8 beta 1(在设备和模拟器上)下工作,但我似乎发现了一个误报,即框架抛出了多线程违规不应该这样做的例外。至少这是我相信的。

问题:下面的代码是正确的还是我正在做一些违反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相同的代码,并得到了相同的结果,所以我怀疑它是一个斯威夫特问题。

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

+0

iOS 8测试版的东西=涵盖NDA ...? – Toastor

+6

不,NDA已被解除:http://oleb.net/blog/2014/06/apple-lifted-beta-nda/ –

+0

哦,很酷!没关系! :) – Toastor

回答

1

苹果确认这是一个错误。它已被修复与Xcode 6测试版4.