Запрос извлечения NSFetchedResultsController - обновление предиката и UITableView - PullRequest
3 голосов
/ 27 марта 2010

В моем приложении iPhone Core Data я настроил его в режиме просмотра основных деталей.

Основным представлением является UITableView, в котором перечислены объекты объекта List. Сущность List имеет отношение ко-многим с сущностью Task (называемой «задачами»), а сущность Task имеет отношение, обратное единице, с List, называемой «списком».

Когда в главном представлении выбран объект List, я хочу, чтобы в подробном представлении (другом UITableView) был указан список Task объектов, которые соответствуют этому объекту List. То, что я сделал до сих пор, это:

В контроллере подробного представления я объявил свойство для List объекта:

@property (nonatomic, retain) List *list;

Затем в главном контроллере представления я использую этот метод делегата табличного представления, чтобы установить свойство list контроллера подробного представления при выборе списка:

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    detailViewController.list = (List*)selectedObject; 
}

Затем я переопределил установщик для свойства list в контроллере подробного представления следующим образом:

- (void)setList:(List*)newList
{
    if (list != newList) {
        [list release];
        list = [newList retain];

        NSPredicate *newPredicate = [NSPredicate predicateWithFormat:@"(list == %@)", list];
        [NSFetchedResultsController deleteCacheWithName:@"Root"];
        [[[self fetchedResultsController] fetchRequest] setPredicate:newPredicate];

        NSError *error = nil;
        if (![[self fetchedResultsController] performFetch:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }       
    }
}

То, что я здесь делаю, это установка предиката для извлеченных результатов, чтобы отфильтровать объекты, чтобы я получал только те, которые принадлежат выбранному List объекту. Метод получения fetchedResultsController для контроллера подробного вида выглядит следующим образом:

- (NSFetchedResultsController *)fetchedResultsController {
    if (fetchedResultsController == nil) {
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Task" inManagedObjectContext:managedObjectContext];
        [fetchRequest setEntity:entity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"FALSEPREDICATE"];
    [fetchRequest setPredicate:predicate];

        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

        [fetchRequest setSortDescriptors:sortDescriptors];

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

        [aFetchedResultsController release];
        [fetchRequest release];
        [sortDescriptor release];
        [sortDescriptors release];
    }

    return fetchedResultsController;
}    

Его значение практически не изменилось по умолчанию в шаблоне проекта Core Data. Внесенное мною изменение заключается в добавлении предиката, который всегда возвращает значение false. Причина в том, что при отсутствии выбранного списка я не хочу отображать какие-либо элементы. в подробном представлении (если выбран список, предикат изменяется в установщике для свойства списка).

Однако, когда я выбираю элемент списка, на самом деле ничего не происходит. Ничего в табличном представлении не меняется, оно остается пустым. Я уверен, что моя логика ошибочна в нескольких местах, совет ценится

Спасибо

Ответы [ 3 ]

1 голос
/ 27 марта 2010

Вам не нужно настраивать NSFetchedResultsController для вашего списка задач. Поскольку вы передаете сущность List, вы можете просто запросить сущность List для задач:

NSSet *tasks = [[self list] valueForKey:@"tasks"];
NSSortDescriptor *sort = ...;
NSArray *sorted = [[tasks allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
[self setTasks:sorted];

Затем методы UITableviewDatasource запускаются из этого массива tasks.

0 голосов
/ 16 августа 2010

Что ж, у меня есть похожая проблема, и я разместил свой вопрос на Как программно переключить NSFetchedResultsController (или его предикат) в UITableView? .

После того, как я его опубликовал, я решилпопробуй свой кодИ знаешь, что?Это работает, только с небольшим дополнением:

    [self.tableView reloadData];

Возможно, вы можете вернуться к исходному коду и подтвердить.

С уважением.

0 голосов
/ 27 марта 2010

Может быть, я не совсем понимаю ваши настройки, но

detailViewController.list.task

(или как там называется эта связь) вернет NSSet любых объектов Task, связанных с объектом List.

...