2014-11-13 3 views
0

(주 스레드 차단을 피하기 위해) 개인 컨텍스트에서 로그인 한 직후 조금 무거운 코어 데이터 삽입 작업 (예 : A)을 수행하고 있습니다. 코드가 완성되기 전에 불행하게도 (B라고도 함) (무거움) 삽입 작업이 있지만 필수적이며 개인 컨텍스트를 사용하여 저장합니다.핵심 데이터 동시성 : 두 개의 별도 위치에서 쓰는 것을 피하십시오.

문제 : 어디 난 이미 DB 또는하지 (독특한 기록을 확인하기 위해)하지만, 위의 작업이 완료되고 난 coredata을 확인 후 나는 단순히있는 일부 레코드가 중복 찾을 수 있는지 여부를 확인 레코드를 저장하는 동안 작업 A에서 '저장'을하기 전에 그로 인해 다른 프로세스 B는 이미 중복 레코드를 작성했습니다.

내가 정착을 찾고, foreseeign 두 가지 옵션 :

  1. 초 작업이 첫 번째 작업을 위해 (다른 스레드에 파견을하고 전까지 완료 대기) 대기
  2. PLZ 추천하자!

편집 : 의 문제가 아니라 동시성보다 합병에 더 관련이 있다고 밝혀지고, 병합 중복 레코드가, 동시성, 발생 오류가 그냥 괜찮 작성

NSCocoaErrorDomain Code=133020 

업데이트 : 병합 문제는 덮어 쓰기 병합 정책으로 수정되었습니다

+0

어쨌든 내가 내 대답을 향상시켜 더 잘 어시스트 할 수 있습니까? –

+0

예, 사실이 질문을 내 코드로 업데이트하려고합니다. 전략은 유용하지만 두 페이지가 같은 페이지에 있다면 다시 돌아올 것입니다. – Firdous

답변

1

당신은 질문에 자신이 말한대로 개체가 복제되고 당신은 두 개의 별개의 장소에서 저축하고 있습니다.

하나의 전략은 동일한 NSManagedObjectContext를 사용하여 모든 쓰기를 수행하는 것입니다. 쓰기를 수행하기 위해 여러 배경 컨텍스트를 만들 필요가 거의 없습니다 (아마도 쓰기 작업이 오래 걸리지 않는 한).

분명히 말해 두 개의 쓰기 작업이 동일한 객체를 쓸 수있는 위치에있게됩니다. 단일 인터페이스를 통해 모든 쓰기를 관리하면이 인터페이스는 쓰기를위한 개인 컨텍스트를 유지합니다. 컨텍스트가 직렬 대기열이기 때문에 동일한 객체를 두 번 쓸 수 없다는 것을 보장 할 수 있습니다 (복제 체크가 견고하다고 가정 할 때).

그래서 인터페이스는 다음과 같습니다

@interface CoreDataManager : NSObject 
+ (CoreDataManager*)sharedManager; 
- (void)performWriteWithBlock:(void (^)(NSManagedObjectContext *writeContext))writeBlock; 
@end 

@implementation CoreDataManager 
+ (CoreDataManager *)sharedManager { 
    static dispatch_once_t once; 
    dispatch_once(&once,^{ 
     self.writeContext = [[self class] createBackgroundPersistanceObjectContext]; 
    }); 
    return sharedManager; 
} 

- (void)performWriteWithBlock:(void (^)(NSManagedObjectContext *writeContext))writeBlock { 
    if (writeBlock) { 
     writeBlock(self.writeContext); 
     [self.writeContext save:nil]; 
    } 
} 

+ (NSManagedObjectContext *)createBackgroundPersistanceObjectContext { 
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [context setPersistentStoreCoordinator:coordinator]; 
    context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy; 
    context.undoManager = nil; 
    return context; 
} 
@end 

그럼에도 불구하고 당신은 인터페이스를 정의하지만, 중요한 것은 당신이 하나의 인터페이스는 코어 데이터 읽기 및 쓰기하여 처리해야한다는 것입니다 수있는 많은 방법이 있습니다.

+1

이 작업을 수행했습니다! "단일 인터페이스를 통해 모든 쓰기를 관리하면이 인터페이스는 쓰기를위한 사적 컨텍스트를 유지합니다. 컨텍스트는 직렬 대기열이므로 동일한 객체를 두 번 쓸 수 없다는 것을 보장 할 수 있습니다", 컨텍스트 전달은 버그, 코드 일관성 문제 해결 – Firdous

+1

@ Firdous Thats 끝내주는 사람! 다행이 도울 수있어 :) –