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 베타가 필요함).
iOS 8 베타 항목 = NDA 적용 ... ...? – Toastor
아니요, NDA가 해제되었습니다. http://oleb.net/blog/2014/06/apple-lifted-beta-nda/ –
오, 멋지다! 그럼, 신경 쓰지 마라. :) – Toastor