2015-12-02 2 views
0

Я изо всех сил пытаюсь интегрировать UICollectionView и NSFetchedResultsControllerDelegate в этом конкретном случае.Как проверить вставленные и удаленные элементы в UICollectionView, увидев неожиданный удаленный элемент

На мой взгляд, контроллер, я получаю родительский объект, но отображаю его несколько дочерних объектов в виде коллекции. При создании нового родительского объекта в этом представлении контроллера (с insertNewObjectForEntityForName) и автоматического создания дочернего объекта и добавления его к родительскому объекту с addChildObject, я могу добавить еще дочерние объекты, нажав кнопку, и сохранить объект успешно. К сожалению, по какой-либо причине методы NSFetchedResultsControllerDelegate не вызываются, в частности, controllerDidChangeContent никогда не вызывается и просмотр коллекции не обновляется.

Когда я принести уже существующий родительский объект, а затем попытаться изменить его путем добавления новых объектов ребенка, приложение падает со следующим исключением:

*** Assertion failure in -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:], 
/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3505.17/UICollectionView.m:4211 

и выдает эту ошибку в конце:

CoreData: error: Serious application error. An exception was caught 
from the delegate of NSFetchedResultsController during a call to 
controllerDidChangeContent:. Invalid update: invalid number of items 
in section 0. The number of items contained in an existing section 
after the update (5) must be equal to the number of items contained in 
that section before the update (4), plus or minus the number of items 
inserted or deleted from that section (1 inserted, 1 deleted) and plus 
or minus the number of items moved into or out of that section (0 moved 
in, 0 moved out). with userInfo (null) 

что меня озадачивает больше всего, в том, что она показывает, что существует удаленный элемент в (1 inserted, 1 deleted), когда, на самом деле, я только добавление элемента (инициализация дочернего объекта с insertNewObjectForEntityForName и добавить его с [parent addChildObject:child].

Во всех этих случаях я не сохраняю контекст. Я ожидаю добавления объектов к родительскому объекту для запуска методов NSFetchedResultsControllerDelegate.

FetchResultsController код установки:

- (NSFetchedResultsController *) fetchedResultsController { 
    if (_fetchedResultsController != nil) { 
     return _fetchedResultsController; 
    } 

    NSFetchRequest *fetchRequest = [self emojiFetchRequest]; 

    _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:nil]; 
    _fetchedResultsController.delegate = self; 

    return _fetchedResultsController; 
} 

Инициализация родительского объекта в viewWillAppear:

[[self fetchedResultsController] performFetch:&error]; 

id fetchedObject = [[[self fetchedResultsController] fetchedObjects] firstObject]; 

if (fetchedObject != nil) { 
    self.parent = (Parent *)fetchedObject; 
    self.navigationItem.title = self.parent.name; 
} else { 
    self.navigationItem.title = @"New parent"; 
    self.parent = [NSEntityDescription insertNewObjectForEntityForName:@"Parent" inManagedObjectContext:[self managedObjectContext]]; 
    Child *child = [NSEntityDescription insertNewObjectForEntityForName:@"Child" inManagedObjectContext:[self managedObjectContext]]; 
    [self.parent addFramesObject:frame]; 
} 

Добавление новых дочерних объектов:

Child *child = [NSEntityDescription insertNewObjectForEntityForName:@"Child" inManagedObjectContext:[self managedObjectContext]]; 
[self.parent addChildrenObject:child]; 

[self.collectionView reloadData]; // if this isn't done, the crash happens 
// but this can't animate changes 

Основные характеристики Модель:

core data model

Есть ли способ увидеть эти объекты? Я пробовал вести журнал didChangeObject, и я вижу только одну вставку. Я ничего не удаляю. Если у кого-нибудь есть другие идеи, я был бы рад услышать их.

EDIT:

Если я позвоню [self.collectionView reloadData] после добавления объектов, кажется, что все правильно работает без сбоев. Но было бы хорошо, если бы изменения были анимированы, чего нельзя сделать с reloadData, и я чувствую, что что-то принципиально неправильно с тем, что я делаю, и я хотел бы исправить это.

+0

Показать изображение модели, код установки FRC и код, добавляющий новые объекты – Wain

+0

@Wain: см. Редактирование. – p4sh4

ответ

0

Лучшее решение: Извлеките объект Child в выбранный вами контроллер результатов, фильтр parent.

Для вставок используйте обычную ванильную реализацию NSFetchedResultsControllerDelegate. Это обеспечит приятную анимацию или позволит вам добавить свой собственный.

+0

Спасибо за ваш ответ. Не могли бы вы объяснить, почему это лучшее решение? Согласно моему пониманию, NSFetchedResultsControllerDelegate не прослушивает изменения в контексте управляемого объекта, и не имеет значения, в каком порядке получаются объекты, если они добавлены в контекст? – p4sh4

+0

Почему «лучший»? Потому что я не могу придумать лучшего или более простого способа. ;-). Порядок выбранных объектов действительно случайный, но ваш запрос на выборку FRC может иметь дескриптор * сортировки *, который позаботится о порядке отображения. - На всякий случай возникает некоторая путаница: выборка, о которой я говорю, выполняется с помощью ** выбранного контроллера результатов **. – Mundi