2014-06-22 1 views
2

부모 - 자식 핵심 데이터 모델의 문제를 해결하는 데 몇 시간을 보냈습니다. 그러나 처음부터 시작합시다. 주요 컨텍스트로 .parentContext있는 주 컨텍스트 및 자식 컨텍스트 있어요.자식 컨텍스트에서 개체를 할당 할 때 관계를 설정할 때 잘못된 시도가 발생했습니다.

- (NSManagedObjectContext *)mainContext { 
    if (!_mainContext) { 
     _mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
     [_mainContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; 
    } 
    return _mainContext; 
} 

- (NSManagedObjectContext *)childContext { 
    if (!_childContext) { 
     _childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
     [_childContext setParentContext:self.mainContext]; 
    } 
    return _childContext; 
} 

다음으로 분리 된 컨텍스트로 두 개의 개체를 만듭니다.

Entity2 *entity2 = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Entity2 class]) 
               inManagedObjectContext:_stack.childContext]; 

Entity1 *entity1 = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Entity1 class]) 
               inManagedObjectContext:_stack.mainContext]; 
entity1.arg1 = @"ABC"; 
entity1.arg2 = @"DEF"; 

모두 괜찮습니다.

그럼 entity1entity2에 추가하려고하든 관계없이 다른 개체의 관계에 하나의 개체를 추가하고 싶습니다.

[entity1 setEntity2:entity2]; 

Multi-Context Core Data | Cocoanetics의 글에서 나는 개체의 서로 모르기 때문에 저장 작업을 가진 블록을 수행해야 함을 읽어 보시기 바랍니다.

[_stack.childContext performBlock:^{ 
    NSError *error; 
    if (![_stack.childContext save:&error]) { 
     NSLog(@"Error: %@", error); 
    } 

    [_stack.mainContext performBlock:^{ 
     NSError *error; 
     if (![_stack.mainContext save:&error]) { 
      NSLog(@"Error: %@", error); 
     } 

     [entity1 setEntity2:entity2]; 
    }]; 
}]; 

을하지만 [entity1 setEntity2:entity2]을 넣어 곳이 끝납니다 : 그래서 다음과 같이 내가 잘못 여기에 무슨 짓을

2014-06-22 08:48:24.444 MultiContextualCoreData[1324:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'entity1' between objects in different contexts (source = <Entity2: 0x8c81570> (entity: Entity2; id: 0x8c80000 <x-coredata:///Entity2/tC31696AE-0A0A-424E-9C8E-1E19085F3FB43> ; data: { 
    entity1 = nil; 
}) , destination = <Entity1: 0x8c80200> (entity: Entity1; id: 0x8c80250 <x-coredata:///Entity1/tC31696AE-0A0A-424E-9C8E-1E19085F3FB42> ; data: { 
    arg1 = ABC; 
    arg2 = DEF; 
    entity2 = nil; 
}))' 
*** First throw call stack: 
(
    0 CoreFoundation      0x01b541e4 __exceptionPreprocess + 180 
    1 libobjc.A.dylib      0x018d38e5 objc_exception_throw + 44 
    2 CoreData       0x00293b7e _PFManagedObject_coerceValueForKeyWithDescription + 3614 
    3 CoreData       0x002614e9 _sharedIMPL_setvfk_core + 185 
    4 CoreData       0x0027ada7 _svfk_0 + 39 
    5 MultiContextualCoreData    0x00002d4a -[AppDelegate test] + 554 
    6 MultiContextualCoreData    0x00002acd -[AppDelegate application:didFinishLaunchingWithOptions:] + 605 
    7 UIKit        0x0058d14f -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 309 
    8 UIKit        0x0058daa1 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1810 
    9 UIKit        0x00592667 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824 
    10 UIKit        0x005a6f92 -[UIApplication handleEvent:withNewEvent:] + 3517 
    11 UIKit        0x005a7555 -[UIApplication sendEvent:] + 85 
    12 UIKit        0x00594250 _UIApplicationHandleEvent + 683 
    13 GraphicsServices     0x03a07f02 _PurpleEventCallback + 776 
    14 GraphicsServices     0x03a07a0d PurpleEventCallback + 46 
    15 CoreFoundation      0x01acfca5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53 
    16 CoreFoundation      0x01acf9db __CFRunLoopDoSource1 + 523 
    17 CoreFoundation      0x01afa68c __CFRunLoopRun + 2156 
    18 CoreFoundation      0x01af99d3 CFRunLoopRunSpecific + 467 
    19 CoreFoundation      0x01af97eb CFRunLoopRunInMode + 123 
    20 UIKit        0x00591d9c -[UIApplication _run] + 840 
    21 UIKit        0x00593f9b UIApplicationMain + 1225 
    22 MultiContextualCoreData    0x00002efd main + 141 
    23 libdyld.dylib      0x0219b701 start + 1 
) 
libc++abi.dylib: terminating with uncaught exception of type NSException 
(lldb) 

?

미리 도움을 주셔서 감사합니다.

답변

7

문제는 두 개체가 서로 간의 관계를 설정하기 위해 동일한 컨텍스트에 속해야한다는 것입니다. 귀하의 경우, 컨텍스트 중 하나는 개인 유형을 가지고 있으며, 그것은 메인 큐가 메인 큐에서 작동하는 자체 큐를 가지고 있습니다. 이것은 길을 따라 동시성 문제가 발생하지 않도록 보호하는 방법입니다.

가능한 해결 방법, 주요 컨텍스트를 저장하려면 entity1 만들기 managedObjectID를 사용하여 아이의 맥락에서이를 검색하거나 더 의미하고 entity1entity2이있는 경우에만 다음 관계를 설정하는 경우 요청을 가져

  • 있습니다 동일한 컨텍스트에서
  • 논리가 허용하는 경우 동일한 컨텍스트에서 두 개체를 모두 만들거나 간단하게 만듭니다.
+1

고마워요, 제게 많은 도움이됩니다. 첫 번째 경우 (동일한 컨텍스트에서 이러한 개체를 만들 수 없기 때문에 NSManagedObjectID 개체를 가져 오는 첫 번째 사례를 사용합니다.) –

+0

속성 주입을 사용하여 동일한 컨텍스트 (옵션 2)에서 두 개체를 모두 만들었고 문제가 해결되었습니다. – Naishta

+0

@ Naishta는 같은 맥락에서 어떻게 개체를 만들 수 있었는지 몇 가지 예를들 수 있습니까? – coolly