1

서버에서 제품 목록을 가져 오는 앱을 만들고 있습니다. 그런 다음 코어 데이터베이스에 저장하고 GMGridView을 사용하여 표시하고 데이터 소스는 NSFetchedResultsController입니다. 서버의 제품 세부 정보를 변경할 때 NSFetchedResultsControllerDelegate 메소드를 구현할 수 있도록 iOS 앱을 동기화하고 필요한 변경 작업을 수행해야합니다. 어떻게하면 gridView를 제대로 업데이트해야합니까?데이터가 업데이트되지 않는 NSFetchedResultsController

- (void)controller:(NSFetchedResultsController *)controller 
    didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath *)indexPath 
    forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath 
{ 
     switch(type) 
     { 
      case NSFetchedResultsChangeInsert: 
       [_currentData insertObject:anObject atIndex:newIndexPath.row]; 
       [_currentData removeObjectAtIndex:indexPath.row]; 
       [_gmGridView insertObjectAtIndex:newIndexPath.row animated:YES]; 
       [_gmGridView removeObjectAtIndex:indexPath.row animated:YES]; 

       [_gmGridView reloadObjectAtIndex:newIndexPath.row animated:YES]; 
       [_gmGridView reloadObjectAtIndex:indexPath.row animated:YES]; 

       [_gmGridView reloadData]; 

       //[self updatePageControl]; 
       break; 

      case NSFetchedResultsChangeDelete: 
       [_currentData removeObjectAtIndex:indexPath.row]; 

       [_gmGridView removeObjectAtIndex:indexPath.row animated:YES]; 
       //[self updatePageControl]; 
       [_gmGridView reloadInputViews]; 
       [_gmGridView reloadData]; 

       break; 

      case NSFetchedResultsChangeUpdate: 
       [_gmGridView reloadObjectAtIndex:indexPath.row animated:YES]; 

       ////////might be irrelevant, but just trying it out 
       [_currentData insertObject:anObject atIndex:newIndexPath.row]; 
       [_currentData removeObjectAtIndex:indexPath.row]; 
       [_gmGridView insertObjectAtIndex:newIndexPath.row animated:YES]; 
       [_gmGridView removeObjectAtIndex:indexPath.row animated:YES]; 

       [_gmGridView reloadObjectAtIndex:newIndexPath.row animated:YES]; 
       [_gmGridView reloadObjectAtIndex:indexPath.row animated:YES]; 

       //////// 


       [_gmGridView reloadInputViews]; 
       [_gmGridView reloadData]; 

       break; 

      case NSFetchedResultsChangeMove: 
       [_currentData removeObjectAtIndex:indexPath.row]; 
       [_currentData insertObject:anObject atIndex:newIndexPath.row]; 
       [_gmGridView removeObjectAtIndex:indexPath.row animated:YES]; 
       [_gmGridView insertObjectAtIndex:newIndexPath.row animated:YES]; 

       [_gmGridView reloadInputViews]; 

       [_gmGridView reloadData]; 

       break; 
     } 
} 

일부 세부 정보 :

_currentData = [[self.fetchedResultsController fetchedObjects]mutableCopy]; 
//I did this because previously I wasn't using a fetchedResultsController but a NSMutableArray instead. I know that it's inefficient (because I have 2 models) but this is the simplest implementation I want to do now. 

나는 같은 로컬 URL에서 같은 UIManagedDocument의 ALLOC, 초기화 에드을 수정하여 다른 클래스의 CoreData을 변경합니다.

는 그러나, 나는이 중요한 문제가 얻을 : 업데이트되는 데이터베이스에

  • 항목을하지만, 변경, UI에 반영되지 않습니다 즉, 내가 할 수 없습니다 (예 : 제품 이름 또는 가격 변경.) 내 GMGridViewCell 제대로 다시로드하십시오. (위에서 로딩과 관련된 코드를 기록해 두십시오.)
  • 이러한 오류를 막을 수있는 메커니즘이 있지만 대부분 서버에서 업데이트 한 제품이 데이터베이스에 복제됩니다. (제품을 만들기 전에 먼저 고유 한 식별자를 사용하여 기존 제품을 검색하고 기존 제품이 있으면 해당 제품의 세부 정보를 수정합니다.) 여기 코드는 다음과 같습니다

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Product"];   

request.predicate = [NSPredicate predicateWithFormat:@"product_id = %@", [imonggoInfo objectForKey:PRODUCT_ID]];  

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];  

request.sortDescriptors = [NSArray 

arrayWithObject:sortDescriptor]; NSError *error = nil; 

NSArray *matches = [context executeFetchRequest:request error:&error]; 

if (!matches | ([matches count] > 1)){ 
    //handle error 
}else if ([matches count] == 0){ 
    //make a new product 
}else{ 
    //return existing 
    item = [matches lastObject]; 
} 

답변

1

내가 NSManagedObjectContextDidSaveNotification을 듣고있는 나는 백그라운드 스레드 주 스레드에서 하나의 수정 된 컨텍스트에서 변경 내용을 병합 할 필요가 밝혀졌습니다. 나는에서 선택한 답에서 아이디어를 얻었다이 question

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextChanged:) name:NSManagedObjectContextDidSaveNotification object:nil]; 

// 그런 맥락에서 변경

- (void)contextDidSave:(NSNotification*)notification{ 
    NSLog(@"contextDidSave Notification fired."); 
    SEL selector = @selector(mergeChangesFromContextDidSaveNotification:); 
    [self.itemDatabase.managedObjectContext performSelectorOnMainThread:selector withObject:notification waitUntilDone:NO]; 
} 
+0

당신은 방법 "contextChanged"에 있지만 예에서 언급하고 병합해야합니다 그 아래에 "contextDidSave"라고 부릅니다. 사소한 세부 사항. –

+0

이제 performBlockAndWait를 사용하여이 작업을 수행 할 수 있습니다. – malhal

관련 문제