NSArrayController инициализация - PullRequest
       5

NSArrayController инициализация

7 голосов
/ 07 декабря 2009

У меня проблемы с получением NSArrayController с базовыми данными для правильной работы в моем коде. Ниже мой код:

pageArrayController = [[NSArrayController alloc] initWithContent:nil];
    [pageArrayController setManagedObjectContext:[self managedObjectContext]];
    [pageArrayController setEntityName:@"Page"];
    [pageArrayController setAvoidsEmptySelection:YES];
    [pageArrayController setPreservesSelection:YES];
    [pageArrayController setSelectsInsertedObjects:YES];
    [pageArrayController setClearsFilterPredicateOnInsertion:YES];
    [pageArrayController setEditable:YES];
    [pageArrayController setAutomaticallyPreparesContent:YES];
    [pageArrayController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES]]];
    BOOL result = [pageArrayController setSelectionIndex:0];

Когда я пытаюсь вызвать setSelectionIndex:, он возвращает YES, указывая, что выбор был успешно изменен. Однако любые последующие вызовы getSelectionIndex к объекту pageArrayController возвращают NSNotFound.

Чего я не понимаю, так это того, что если я помещаю NSArrayController в NIB и разрешаю файлу NIB выполнять инициализацию (со всеми теми же атрибутами в Interface Builder), NSArrayController работает правильно.

Почему существует разница в поведении? Файл NIB инициализирует эти типы объектов особым образом? Моя инициализация NSArrayController неверна?

Любая помощь приветствуется. Благодаря.

Ответы [ 3 ]

15 голосов
/ 07 декабря 2009

Да, перья действительно инициализируют объекты особым образом, и иногда бывает сложно понять, как это повторить. Я тоже боролся с этим и, наконец, нашел ответ в Руководстве по программированию основных данных Apple >> Базовые данные и привязки Cooca >> Автоматически подготавливать флаг содержимого (благодаря Дэйву Фернандесу на Cocoa Dev список). Ответ таков: если вы инициализируете контроллер массива с нулевым содержимым, вам также необходимо выполнить выборку.

BOOL result;
NSArrayController *pageArrayController = [[NSArrayController alloc] initWithContent:nil];
[pageArrayController setManagedObjectContext:[self managedObjectContext]];
[pageArrayController setEntityName:@"Page"];
NSError *error;
if ([pageArrayController fetchWithRequest:nil merge:YES error:&error] == NO) 
     result = NO;
else
{
     //do all that other pageArrayController configuration stuff
     result = [pageArrayController setSelectionIndex:0];
}

Кстати, [NSSortDescriptor sortDescriptorWithKey: @ "index" ascending: YES]] выдает предупреждение.

0 голосов
/ 07 декабря 2009

Откуда вы создаете / конфигурируете свой контроллер массива? Стек основных данных может быть еще не готов, поэтому ваш вызов [selfagedObjectContext] может возвращать ноль.

Кроме того, почему вы создаете это программно, если вы можете сделать это просто отлично с Interface Builder? Инструмент есть и работает хорошо (и устраняет множество возможных ошибок кодирования), поэтому, если у вас нет веских причин не использовать его, вы не оказываете никакой пользы.

0 голосов
/ 07 декабря 2009

Насколько может быть разница в поведении:

  1. Файлы Nib хранят сериализованные объекты с использованием NSCoder.
  2. Вы, вероятно, используете связывание на стороне IB, где в своем коде вы устанавливаете контекст управляемого объекта напрямую, используя метод set.

Может быть, вы могли бы попробовать что-то вроде следующего в вашем коде:

[pageArrayController bind:@"managedObjectContext"
                 toObject:self
              withKeyPath:@"managedObjectContext"
                  options:nil];

У меня нет Xcode рядом, иначе я бы попробовал кое-что. Надеюсь, это даст вам некоторые подсказки, чтобы вы пошли в правильном направлении.

...