Организация основных данных объектов в разделы - PullRequest
2 голосов
/ 29 августа 2011

У меня есть следующая модель данных:

managed object structure

После открытия документа я бы хотел перечислить слои (как разделы) с базовыми объектами в UITableView. Я реализовал полученный контроллер результатов следующим образом:

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

    // Create the fetch request for the entity
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"DB_Layer" 
        inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size
    [fetchRequest setFetchBatchSize:10];

    // Sort by stacking order, descending
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
        initWithKey:@"stackingOrder" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];

    // Create the fetched results controller, and set this controller to be the delegate
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] 
        initWithFetchRequest:fetchRequest 
        managedObjectContext:managedObjectContext 
        sectionNameKeyPath:nil cacheName:@"Layer"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    // Fetch the results into the fetched results controller
    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return fetchedResultsController;
}

Проблема в том, что это дает мне список всех слоев (даже тех, которые принадлежат другим документам). Я считаю, что я должен использовать NSPredicate, чтобы сузить результаты, но я не уверен, как.

Что мне нужно, это:

  • список, организованный в разделы по DB_Layer объектам (я не уверен, где я могу указать, по чему можно группировать результаты)
  • каждый раздел, содержащий объекты / группы соответствующего слоя.

EDIT:

Основываясь на ответе Ричарда Кейси, я теперь могу получить список слоев, но он требует, чтобы я извлек все DB_Shape объектов (даже принадлежащих другим документам) и отфильтровал их с помощью предикатов. Это большой успех производительности.

То, что я действительно ищу, это способ сделать это наоборот:

  • передать текущий документ в NSFetchedResultsController,
  • извлечение связанных объектов, создание раздела для каждого DB_Layer объект,
  • список соответствующих - либо сгруппированных (DB_Group), либо отдельных (DB_Shape) объекты в разделе.

Ответы [ 4 ]

2 голосов
/ 30 августа 2011

То, что я действительно ищу, это способ сделать это наоборот:

  • передать текущий документ в NSFetchedResultsController,
  • получить связанные объектысоздавая раздел для каждого объекта DB_Layer,
  • перечисляет соответствующие - либо сгруппированные (DB_Group), либо отдельные (DB_Shape) объекты в разделе.

A NSFetchResultsController может вернуть только один вид сущности.Таким образом, вы не можете перечислить как DB_Group, так и DB_Shape сущности с текущей моделью.Сущность DB_Group делит все атрибуты с DB_Shape, так что вы можете сделать DB_Shape субъектом DB_Group.

Таким образом, DB_Layer имеет только отношение «один ко многим» для отношения DB_Group, что так случилось, что включают в себя формы, а также.Затем вы получите запрос:

  • Извлечение DB_Group сущностей.
  • Группировка по DB_Layer.
  • Отфильтровано по предикату на основе слоев DB_Document.

Для презентации вы используете isKindOfClass:, если вам нужны разные типы представлений для групп и фигур.

2 голосов
/ 30 августа 2011

Не совсем ответ на ваш вопрос, но если у вас в руке есть конкретный объект DB_Document, вам не нужно извлекать его, вы просто запрашиваете у объекта содержание его отношения layer и затем идете оттуда,

Это скорее весь смысл отношений.Вы уже знаете, какие объекты вам нужны, и у вас нет фильтрации всего постоянного хранилища, которое выглядит из них.

2 голосов
/ 29 августа 2011

Вы правы. Чтобы составить список слоев для конкретного документа, вы можете использовать NSPredicate.

Следующий код (добавленный перед созданием NSFetchedResultsController) должен это сделать.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"document.name == %@",docName];
[fetchRequest setPredicate:predicate];

Переменная docName в приведенном выше коде является атрибутом имени документа, который вы хотите просмотреть.

Когда вы создаете NSFetchedResultsController, параметр sectionKeyNamePath указывает атрибут, который используется для создания групп для вашего табличного представления. Если вы хотите перечислить объекты / группы по соответствующему слою, вы, вероятно, захотите запустить NSFetchRequest для сущности DB_Shape, а затем использовать @ "layer.name" для sectionKeyNamePath.

Надеюсь, это поможет!

0 голосов
/ 29 августа 2011

Не уверен, как выглядит структура вашего объекта DB_Layer, но вы можете изменить инициализацию NSFetchedResultsController следующим образом, чтобы указать поле в DB_layer, для которого вы хотите создать раздел.Например, если у вас есть поле с именем «field1» в вашем основном объекте данных, на котором вы хотите разделить свои результаты, обновление sectionNameKeyPath должно создать разделы для вас:

// Create the fetched results controller, and set this controller to be the delegate
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] 
    initWithFetchRequest:fetchRequest 
    managedObjectContext:managedObjectContext 
    **sectionNameKeyPath:@"field1"** cacheName:@"Layer"];

Использование предиката отфильтрует ваширезультаты - не уверен, что это то, что вы после.Приведенный выше фрагмент должен сгруппировать ваши результаты в разделы, основанные на «field1».

...