2009-12-07 8 views
7

У меня возникли проблемы с тем, чтобы NSArrayController поддерживал основные данные, чтобы нормально работать в моем коде. Ниже мой код:Инициализация 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?

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

+0

Существует не такая вещь, как метод '-getSelectionIndex'. Вы сами пишете такой метод или на самом деле называете что-то другое? –

+0

Я имел в виду -selectionIndex. –

ответ

14

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

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: @ "Индекс" по возрастанию: YES]] вызывает предупреждение.

+0

Кроме того, ваше использование [self managedObjectContext] подразумевает, что вы добавили методы pageArrayController в appDelegate. Это не считается хорошей практикой.Вы действительно должны задуматься о создании отдельного объекта контроллера страницы (а также моделировать и просмотреть объекты, если необходимо для реализации шаблона MVC), которые будут заботиться о всех функциях страницы вашего приложения. Объект страницы или объекты модели страницы может вызвать [[NSApp delegate] managedObjectContext], когда это необходимо. –

+0

Спасибо за это решение, он отлично работает. Теперь моя структура приложения намного приятнее, и я могу создать эти контроллеры массивов в коде, а не полагаться на перья. –

+0

Ты, мой друг, легенда! Я потратил дни, пытаясь понять, почему мой контроллер массива не обновлялся, так как новые данные попали в мое хранилище Core Data из iCloud. Теперь он работает отлично. Спасибо. – Fin

0

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

  1. СИБ файлы хранят сериализованные объекты с помощью NSCoder.
  2. Возможно, вы используете привязку к стороне IB вещей, где в вашем коде вы напрямую настраиваете контекст управляемого объекта, используя метод set.

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

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

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

0

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

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

+0

В моем случае я создаю NSArrayController в коде, так как при использовании IB привязанные данные в NSArrayController еще не загружены в 'awakeFromNib'. Вы знаете, как решить проблему в IB? – xyz

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