2009-10-13 2 views
0

내 데이터 소스로 NSFetchedResultsController가 있는데 내 사용자 지정 UITableViewController에 NSFetchedResultsControllerDelegate를 구현합니다. sectionNameKeyPath를 사용하여 결과 세트를 여러 섹션으로 나누었습니다.NSFetchedResultsController로 섹션 삽입을 처리하는 방법은 무엇입니까?

내 방법 중 하나에서 컨텍스트에 몇 가지 개체를 추가합니다.이 개체는 모두 새로운 섹션에 있습니다. 개체를 저장하는 순간에 대리자 메서드가 제대로 호출됩니다. 이벤트의 순서 :

Serious application error. Exception was caught during Core Data change processing: 
[NSCFArray objectAtIndex:]: index (5) beyond bounds (1) with userInfo (null) 

테이블 업데이트가 일부에서 NSFetchedResultsController 데이터와 동기화되지 않은 것으로 보인다 :

// -controllerWillChangeContent: fires 
[self.tableView beginUpdates]; // I do this 

// -controller:didChangeSection:atIndex:forChangeType: fires for section insert 
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]]; 

// -controller:didChangeObject:atIndexPath:forChangeType:newIndexPath fires many times 
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
       withRowAnimation:UITavleViewRowAnimationFade]; // for each cell 

// -controllerDidChangeContent: fires after all of the inserts 
[self.tableView endUpdates]; // <--- Where things go terribly wrong!!! 

마지막 호출에는 "EndUpdates 사이는"응용 프로그램이 항상 함께 충돌 길, 그리고 물건은 날아 오른다. NSFetchedResultsControllerDelegate에 대한 문서를 따르고 있지만 작동하지 않습니다. 그것을하는 올바른 방법은 무엇입니까?

업데이트 : 나는이 버그를 보여주는 테스트 프로젝트를 만들었습니다. 당신은 그것을 통해 다운로드 할 수 있습니다 : NSBoom.zip

답변

1

나는 전체 섹션을 삽입하고 didChangeSection가 먼저 호출 된 didChangeSection이 먼저 호출 된 다음 didChangeObject가 반복적으로 호출됨을 알 수 있습니다.

didChangeSection에서 전체 섹션을 삽입 한 다음 테이블 뷰를 업데이트하기 직전에 동일한 섹션에 개체를 추가하는 것이 문제입니다. 이것은 기본적으로 중복 된 업데이트의 경우입니다 ... (시작/끝 업데이트 블록에서도 허용되지 않음).

당신은 개별 개체 삽입을 주석 경우, 모든 작품 :

case NSFetchedResultsChangeInsert: 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

이 섹션 삽입을 주석 경우 :, 그것이 작동하지 않습니다 -하지만 난 모든 작업 insertRowsInSections으로 덜 행운이 있었다 시간이 걸릴 수 있습니다. 그리고 섹션이 아직 없기 때문일 수도 있습니다. (필자가 섹션을 삽입하는 이유는 확실합니다.) 올바른 세분성으로 삽입을 수행하기 위해 두 경우를 감지해야 할 수도 있습니다.

일반적으로 행보다 전체 행을 다시로드하고 삽입하는 행운을 많이 봤습니다. 테이블 뷰는 작업하는 사람들에게 내게 매우 겁나는 것처럼 보입니다. 성공적으로 더 자주 작동하는 것으로 보이는 UITableViewRowAnimationNone을 시도 할 수도 있습니다.

+0

감사합니다. 그 관찰 (더블 업데이트)은 내가 사용할 수있는 해결 방법을 찾도록 해주었습니다. –

0

동일한 문제가 있습니다. 나는 그 didChangeSection가 두 번 발사하는 것을 발견한다. 삽입 할 객체를 만들 때 한 번, 실제로 저장할 때 한 번. 나에게 그것은 save가 호출 될 때까지 didChangeSection을 호출하면 안된다. 또는 최소한 willChangeSection은 객체 생성시 호출되고 didChangeSection은 저장 될 때 호출됩니다.

이제 NSManagedObjectContextDidSaveNotification 옵저버 메서드를 살펴 보겠습니다. 이 프로토콜은 NSFetchedResultsControllerDelegate 프로토콜의 일부는 아니지만 등록하여 등록 할 수 있습니다. 아마 실제로 호출 할 때 호출됩니다 전에 저장하지 않고 전에.