NSArrayController создание, изменение, а затем выбор нового объекта - PullRequest
1 голос
/ 25 января 2010

Основным видом моего приложения на основе NSPersistentDocument является табличное представление (привязанное к NSArrayController), показывающее список записей, под ним есть кнопка «Добавить запись». Я хочу, чтобы кнопка вызывала следующее (предположительно тривиальное) поведение.

  1. Создать новый объект
  2. Установить некоторые значения по умолчанию для нового объекта (которые хранятся в основном документе и не доступны глобально)
  3. Добавьте его в представление таблицы.

Вот то, что я пытался или отклонил:

  1. использовать NSArrayController «добавить» действие - проблема: не вернет новый объект и реализация будет отложена, поэтому невозможно изменить вновь созданный объект
  2. Переопределить инициализацию класса данных - не будет работать - мне нужно получить доступ к данным, которые хранятся в экземпляре класса документа
  3. Подкласс NSArrayController и переопределение "newObject" - снова - не будут работать, потому что мне нужен доступ к данным, хранящимся в документе.
  4. Сработал следующий код «почти»:

    - (IBAction)newRecord:(id)sender
    {
        MyDataClass *newRecord = [recordsArrayController newObject];
    
        newRecord.setting1=self.defaultSetting1;
        newRecord.setting2=self.defaultSetting2;
        // ... etc...
        [recordsArrayController addObject:newRecord];
        [recordsTable scrollRowToVisible:[recordsTable selectedRow]];
        [newRecord release];    
    }
    

Этот код действительно хорошо работает для несохраненных документов. Но если я сохраню документ и снова открою его, то после нажатия кнопки «Добавить» новая запись отобразится в таблице дважды. Очевидно, что addObject является избыточным (хотя он отлично работает в несохраненных документах), но без него новый объект не выделяется.

Ответы [ 2 ]

2 голосов
/ 25 января 2010

Простой случай, который должен работать:

MyDataClass *newRecord = [controller newObject];
// configure newRecord
[controller addObject:newRecord];
[newRecord release];

Для выбора нового объекта необходимо предварительно настроить контроллер на -setSelectsInsertedObjects:YES.

Но есть альтернатива, которую я бы счел более подходящей. Подкласс NSArrayController вроде так (неряшливый псевдокод):

@interface MyRecordController : NSArrayController
@property id recordSetting1;
@property id recordSetting2;
@end

@implementation MyRecordController

@synthesize recordSetting1;
@synthesize recordSetting2;

- (id)newObject
{
    id result = [super newObject];
    newRecord.setting1 = self.recordSetting1;
    newRecord.setting2 = self.recordSetting2;
    return result;
}

@end

Итак, ваш код становится:

- (IBAction)newRecord:(id)sender
{
    recordsArrayController.recordSetting1 = self.defaultSetting1;
    recordsArrayController.recordSetting2 = self.defaultSetting2;
    [recordsArrayController add:self];    
}
1 голос
/ 25 января 2010

Действительно, все, что вам нужно сделать, это изменить свой код, чтобы пропустить вызов addObject:. Чтобы выделить новый объект, просто сделайте это:

[recordsArrayController setSelectedObjects:[NSArray arrayWithObject:newObject]];

перед тем, как позвонить на swcrollRowToVisible:. Вы правы, что звонок addObject: не нужен. Как вы уже видели, он дважды попадает в контроллер массива.

Кроме того, вам не нужно будет звонить [newRecord release]. В документации говорится, что объект сохраняется контроллером массива. Это не сбой сейчас, потому что он сохраняется во второй раз, когда вы делаете addObject:.

...