2010-07-02 2 views
3

Я реализую UITableViewController в сочетании с NSFetchedResultsController. Когда экземпляр UITableViewController создан, NSFetchedResultsController сконструирован (по существу, так же, как пример CoreDataBooks) с другим предикатом, основанным на выборе пользователя, сделанного на предыдущем контроллере.
Иногда я установил предикат следующим образом:NSFetchedResultsControllerDelegate методы не вызывается, если его предикат использует IN?

predicate = [NSPredicate predicateWithFormat:@"container = %@", aManagedObject]; 

иногда таким образом:

predicate = [NSPredicate predicateWithFormat:@"container IN (%@)", aNSMutableSetOfObjectsID]; 

Оба предиката работает нормально, потому что они выборки правильно все мои объекты, как и ожидалось. Проблема возникает, когда я пытаюсь вставить новый управляемый объект в список, когда установлен второй предикат. Infact в этом случае методы делегата FRC никогда не вызываются, поэтому tableview не обновляется автоматически.
Я уверен, что новый объект правильно добавлен в тот же контекст, который используется FRC, и что его отношение «контейнер» установлено так, что делегат должен быть запущен, но это не так!

То, что я пробовал:

Я говорю о том, что второй предикат работает нормально, потому что, если добавить новый объект, а затем вытолкнуть UITableViewController и нажмите на нее снова, заставляя все данные, которые будут refetched, новый объект появляется в списке без проблем.
Другого тест, который я сделал, чтобы заставить FRC быть пересчитан мгновенным после добавления нового объекта:

NSError *error = nil; 
if (![[self fetchedResultsController] performFetch:&error]) { 
    exit(-1); 
} 
[self.tableView reloadData]; 

нового объект отображается правильно.

Код:

- (NSFetchedResultsController *)fetchedResultsController { 
if (fetchedResultsController == nil) { 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSManagedObjectContext *managedObjectContext = realEstate.managedObjectContext; 

    [fetchRequest setEntity:[NSEntityDescription entityForName:@"Item" inManagedObjectContext:managedObjectContext]];  
    [fetchRequest setPredicate:[self getBasePredicate]]; 

    NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" 
                    ascending:YES 
                    selector:@selector(localizedCaseInsensitiveCompare:)]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:nameDescriptor, nil]; 
    [fetchRequest setSortDescriptors:sortDescriptors]; 
    [nameDescriptor release]; 
    [sortDescriptors release]; 

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                           managedObjectContext:managedObjectContext 
                            sectionNameKeyPath:@"sectionIndex" 
                              cacheName:nil]; 
    self.fetchedResultsController = aFetchedResultsController; 
    fetchedResultsController.delegate = self; 
    [aFetchedResultsController release]; 
    [fetchRequest release]; 
} 

return fetchedResultsController; 
} 


// return a predicate for the fetchedResultsController 
- (NSPredicate *)getBasePredicate { 
    NSPredicate *predicate = nil; 

    if ([[managedObject valueForKey:@"subcontainersCount"] intValue] == 0) 
     // container without sons **(FIRST PREDICATE)** 
     predicate = [NSPredicate predicateWithFormat:@"container = %@", managedObject]; 
    else { 
     // container with sons **(SECOND PREDICATE)** 
     predicate = [NSPredicate predicateWithFormat:@"container IN (%@)", [Container allDescendantsObjectID:(Container *)managedObject includeSource:YES]]; 
    } 

    return predicate; 
} 


- (void)addNewItem { 
    Item *newItem = (Item *)[NSEntityDescription insertNewObjectForEntityForName:@"Item" 
                  inManagedObjectContext:realEstate.managedObjectContext]; 
    newItem.name = @"my new item"; 
    newItem.container = aContainerManagedObject; 

    NSError *error = nil; 
    if (![realEstate.managedObjectContext save:&error]) { 
     abort(); 
    } 
} 

Методы NSFetchedResultsControllerDelegate я использую, взяты из "More iPhone 3 развития". Полный код может быть указан here (стр. 30-31, 35).
Я могу разместить здесь, если необходимо.

ответ

2

Решено заменить идентификатор объекта NSManagedObject в предикат.

До: [NSPredicate predicateWithFormat:@"container IN (%@)", aNSMutableSetOfObjectsID];

После: [NSPredicate predicateWithFormat:@"container IN (%@)", aNSMutableSetOfNSManagedObject];

По некоторым причинам делегат FRC не вызывается, если предикат выборки объектов с использованием идентификатора вместо точных NSManagedObjects.
Я тестирую iPhoneOS 3.1.3 и 3.2. Однако iPhoneOS 4.0 должен поддерживать как объектыID, так и NSManagedObject и корректно вызывать методы делегатов FRC, но я не могу протестировать 4.0 на данный момент.

+0

Спасибо! У меня также была проблема, когда делегат FRC не вызывался, и хотя это была другая проблема, это оказалось проблемой для моего предиката. –

Смежные вопросы