2014-06-11 2 views
10

WWDC 2014 session 225 (코어 데이터의 새로운 기능)에서 설명한대로, iOS 8 및 OS X의 코어 데이터 요즘은 코어 데이터의 동시성 계약 위반을 탐지하는 어설 션을 활성화하기 위해 명령 줄 인수 -com.apple.CoreData.ConcurrencyDebug 1을 지원합니다 .코어 데이터 동시성 디버깅 : 거짓 긍적

내 실험에서이 장치가 iOS 8 베타 1 (장치와 시뮬레이터 모두에서 작동 함)에서 작동하지만 거짓 긍정을 발견 한 것 같습니다. 즉 프레임 워크에서 멀티 스레딩 위반이 발생했습니다. 예외로해서는 안됩니다. 적어도 그것이 내가 믿는 것입니다.

질문 : 코드가 정확합니까? 아니면 핵심 데이터의 스레딩 모델을 위반하는 작업을하고 있습니까?

내가하는 일은 개인 큐 동시성이있는 backgroundContext이라는 관리되는 개체 컨텍스트를 사용하는 매우 간단한 핵심 데이터 스택 (메모리 저장 공간 포함)을 설정하는 것입니다. 그런 다음 해당 컨텍스트에서 performBlockAndWait { }을 호출하고 블록에서 새 관리 대상 개체를 만들고이를 컨텍스트에 삽입하고 저장합니다.

저장 작업은 핵심 데이터에서 다중 스레드 위반 예외가 발생하는 곳입니다.

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

Apple은 버그로 확인했습니다. Xcode 6 베타 4로 수정되었습니다.