1

백그라운드에서 코어 데이터를 더 쉽게 수행 할 수있는 몇 가지 방법을 만들려고합니다. 내가하고 있어요 것은 :실행 후 백그라운드에서 삭제가 작동하지 않습니다.

  • 사용 NSOperationQueue-addOperationWithBlock:는 메인 스레드와 undoManager 세트와 컨텍스트와 같은 persistentStoreCoordinator와 함께 NSManagedObjectContext를 작성, 백그라운드 스레드에서 백그라운드 스레드
  • 를 만들

    - (void)mergeChanges:(NSNotification *)notification 
    { 
        dispatch_sync(dispatch_get_main_queue(), ^{ 
         [_mainContext mergeChangesFromContextDidSaveNotification:notification]; 
        }); 
    } 
    
  • : nil
  • NSManagedObjectContextDidSaveNotification 알림을 수신 할이처럼 그들을 처리하는 기본 알림 센터에 관찰자를 추가

  • 전달 된 블록을 실행하고 모든 핵심 데이터 항목을 수행합니다. 주기적으로,이 모든 것이 완료되면 배경 컨텍스트

  • save:를 호출 기술 된 방법은 아래에서 확인할 수있는 알림 센터

에서 관찰자를 제거합니다.

모든 것이 예상대로 작동합니다. 데이터를 추가하거나, 데이터를 업데이트하거나, 데이터를 제거하는 블록을 전달할 수 있습니다. 그러나는 :

CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. CoreData could not fulfill a fault for [...]

오류에서 알 수있는 바와 같이

, 내가 NSFetchedResultsController을 사용하고 있습니다 : 나는 일부 데이터와 응용 프로그램을 닫을 때 나는 백그라운드에서 데이터를 삭제하려고 다음을 다시 열고, 다음과 같은 오류가 데이터를 표시합니다. 컨트롤러의 캐시는 nil으로 설정됩니다.

이 문제를 해결하는 방법에 대한 제안 사항이 있으십니까?


다음은 관련 코드입니다. ARC를 사용하고 있습니다.

FJCoreDataBackgroundBlock

은과 같이 정의된다 :

+ (NSOperationQueue *)sharedQueue 
{ 
    static dispatch_once_t predicate = 0; 

    __strong static NSOperationQueue *_sharedQueue = nil; 

    dispatch_once(&predicate, ^{ 
     _sharedQueue = [[NSOperationQueue alloc] init]; 
     [_sharedQueue setMaxConcurrentOperationCount:1]; 
    }); 

    return _sharedQueue; 
} 

+ (void)addOperationWithBlock:(void (^)(void))block 
{ 
    [[FJSharedOperationQueue sharedQueue] addOperationWithBlock:block]; 
} 

답변

0

지금 :

typedef void(^FJCoreDataBackgroundBlock)(NSManagedObjectContext *backgroundContext); 

방법은 FJSharedOperationQueue의 구현 배경

- (void)performBlockInBackground:(FJCoreDataBackgroundBlock)block 
{ 
    [FJSharedOperationQueue addOperationWithBlock:^{ 

     self.managedObjectContext = [[NSManagedObjectContext alloc] init]; 
     [_managedObjectContext setUndoManager:nil]; 
     [_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; 

     [self setupNotificationCenterObserverForContext:_managedObjectContext]; 

     FJCoreDataBackgroundBlock backgroundBlock = [block copy]; 
     backgroundBlock(self.managedObjectContext); 

     [self saveBackgroundContext]; 
     [self saveMainContext]; 
     [self removeNotificationCenterObserver]; 
    }]; 
} 

에서 코어 데이터 물건의 무리를 수행하기 위해 그 이상한입니다 : 나는 블록 t에서 코드 라인을 따라 걷고 있었다. 모자는 객체를 삭제합니다. 그것은이처럼 보였다 전에 :

FJCoreDataHelper *helper = [[FJCoreDataHelper alloc] initUsingMainManagedObjectContext:[self mainContext]]; 

[helper performBlockInBackground:^(NSManagedObjectContext *backgroundContext) { 

    // [Fetch objets here...] 

    // Delete: 

    const int kSaveThreshold = 50; 
    for (int card = 0, count = [allCards count]; card < count; card++) 
    { 
     [backgroundContext deleteObject:[allCards objectAtIndex:card]]; 

     if (card % kSaveThreshold == 0) 
     { 
      [helper saveBackgroundContext]; 
     } 
    } 
    }]; 

이 문제를 해결하려면, 단순히 배경 컨텍스트를 저장 한 후 주요 컨텍스트를 저장했다 :

[helper performBlockInBackground:^(NSManagedObjectContext *backgroundContext) { 

    // [Fetch objets here...] 

    // Delete: 

    const int kSaveThreshold = 50; 
    for (int card = 0, count = [allCards count]; card < count; card++) 
    { 
     [backgroundContext deleteObject:[allCards objectAtIndex:card]]; 

     if (card % kSaveThreshold == 0) 
     { 
      [helper saveBackgroundContext]; 
      [helper saveMainContext]; 
     } 
    } 
    }]; 

을 난 단지 배경 컨텍스트를 저장하면 충돌이 발생합니다. 주 컨텍스트를 먼저 저장하면 충돌이 발생합니다. 배경 컨텍스트를 주 컨텍스트로 병합하면 주 컨텍스트를 저장할 수 있다고 생각했기 때문에이 이상한 것을 발견했습니다.

관련 문제