2012-06-05 2 views
2

저는 거의 모든 것을 시도했지만 잘못 된 것을 알 수는 없습니다. NSFetchedResultsController 있고 코어 데이터 일부 게시물을 가져옵니다. 그런 다음 동일한 컨텍스트에 새 게시물을 삽입하고 컨텍스트를 저장하는 방법이 있습니다. 일반적으로 didChangeObject : 메서드는 지금 호출되어야하지만 그렇지 않습니다. 나는 기본적으로 다른 테이블 (= nsmanaged 오브젝트)에서 동일한 뷰 컨트롤러를 가지고 있고 거기에 didChangeObject : 메소드가 성공적으로 호출된다.didChangeObject : NSFetchedResultsController가 호출되지 않았습니다.

지금까지 시도하는 것 : 그냥 NSFetchedResultsController

다음 방법의 캐시를 삭제이보기 컨트롤러

  • 또 다른 컨텍스트를 생성

    • 데이터를 가져옵니다 코어 데이터 db를 추출하고 NSFetchedResultsController (변수 : controller)에 '저장'합니다.

      //reloading newsgroups from coredata 
      - (void)reloadNewsgroupsFromCoreData 
      {  
          //creating fetch request 
          NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Post"]; 
      
          //sorting by transient date (hour and secons cutted off) 
          NSSortDescriptor *sortByDate = [[NSSortDescriptor alloc] initWithKey:@"dateCreatedTransient" ascending:NO]; 
          NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortByDate, nil]; 
          [fetchRequest setSortDescriptors:sortDescriptors]; 
      
          //where clause 
          [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"ref_subscribed_newsgroup == %@ AND references == nil", self.newsgroup]]; 
      
          //setting fetchrequest 
          self.controller = [[NSFetchedResultsController alloc] 
               initWithFetchRequest:fetchRequest 
               managedObjectContext:self.context 
               sectionNameKeyPath:@"dateCreatedForSections" 
               cacheName:nil]; //todo, maybe add a cache here! 
      
          //fetch 
          NSError *error; 
          [self.controller performFetch:&error]; 
      
          if (error) { 
           NSLog(@"%@", error); 
          } 
      } 
      

      또한, 문서에있어서 I (이 페치 한 방법의 위치와 동일하다) 내보기 컨트롤러에 NSFetchedResultsController의 대리인 설정. viewDidLoad에서

      :

      self.controller.delegate = self; 
      

      그러면 I 프로토콜의 방법을 구현 한도 didChangeObject:

      - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {  
          UITableView *tableView = self.tableView; 
      
          // I HAVE ADDED A BREAKPOINT HERE BUT IT NEVER STOPS HERE. 
      
          switch(type) { 
      
           case NSFetchedResultsChangeInsert: 
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      
            break; 
           case NSFetchedResultsChangeDelete: 
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
            break; 
      
           case NSFetchedResultsChangeUpdate: 
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] 
              atIndexPath:indexPath]; 
      
            break; 
      
           case NSFetchedResultsChangeMove: 
            [tableView deleteRowsAtIndexPaths:[NSArray 
                     arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
            [tableView insertRowsAtIndexPaths:[NSArray 
                     arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
            break; 
          } 
      
      } 
      

      그럼 코어 데이터로 일부 포스트를 저장하는 다른 방법이있다. 나는 이것이 중요하다고 생각한다.이 메서드는 다른 스레드의 델리게이트를 통해 호출된다. (서버 연결은 performSelectorOnMainThread:...를 사용하여 호출)

      - (void)storeIntoCoreData:(NSArray*)postsArray 
      { 
      ... 
           Post *entity = [NSEntityDescription insertNewObjectForEntityForName: @"Post" inManagedObjectContext:context]; 
      
           entity.inReply = dummy.in_reply; 
           entity.body = dummy.body; 
           entity.email = dummy.email; 
           entity.from = dummy.from; 
           entity.messageIdentifier = dummy.message_identifier; 
           entity.references = dummy.references; 
           entity.subject = dummy.subject; 
           entity.dateCreated = dummy.date; 
           entity.unread = [NSNumber numberWithInt:1]; 
      ... 
          [self.context save:&error]; 
          if (error) 
          { 
           NSLog(@"error: %@", error); 
          } 
      
      // IMPORTANT: CURRENTLY I AM CALLING THIS METHOD AGAIN HERE, WHICH 
      // FETCHES ALL POSTS OUT OF CORE DATA. 
      // THIS IS SO UGLY AND NOT PERFORMANT. 
      // THEN I INVOKE RELOADDATA ON THE TABLEVIEW TO RELOAD THE ENTIRE TABLE 
      // BUT THERE WAS JUST ONE INSERT SO A ENTIRE RELOAD WOULD NOT BE NECESSARY. 
          [self reloadNewsgroupsFromCoreData]; 
          [self.tableView reloadData]; 
      
      // I HAVE TO DO THIS BECAUSE THE didChangeObject METHOD GETS NOT CALLED. 
      } 
      

      사람이 힌트 또는 잘못 될 수 있는지 제안이 있습니까?

      감사와 관련, 크리스

  • 답변

    4

    문제는 당신이 viewDidLoad에 컨트롤러 대리자를 설정하고 나중에 reloadNewsgroupsFromCoreData에 새로운 컨트롤러를 할당하고 있다는 점이다. 새로 할당 된 컨트롤러에는 위임 집합이 없습니다. 대리인을 reloadNewsgroupsFromCoreData에 직접 설정해보세요.

    일반적으로 데이터가 변경 될 때마다 NSFetchedResultsController을 새로 할당하지 않으려합니다. NSFetchedResultsController을 사용하는 요점은 무엇인가 변경되면 NSFetchedResultsControllerDelegate을 통해 위임 메시지를받는 것입니다. 가져 오기 요청이 변경되는 경우에만 NSFetchedResultsController을 새로 할당해야합니다. Apple Docs을 다시 살펴 보시기 바랍니다.

    관련 문제