2010-01-25 2 views
1

Основной вид моего приложения на основе NSPersistentDocument - это представление таблицы (связанное с NSArrayController), отображающее список записей, под ним есть кнопка «добавить запись». Я хочу, чтобы кнопка вызывала следующее (предположительно тривиальное) поведение.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» является избыточным (хотя он отлично работает в несохраненных документах), но без него новый объект не выбран.

ответ

1

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

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

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

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

+0

неправильно, вам нужно вызвать '[newRecord релиз]'. Создание его с помощью '-newObject' дает ему значение сохранения +1. –

+0

Помимо аргумента по счету сохранения, этот ответ работает и является гораздо лучшим ответом, чем подкласс NSArray. –

+0

Спасибо, решение работает. Комментарий относительно «relaese» действительно неверен, newObject дает вам сохраненный объект, который вам нужно освободить. –

2

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

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

Для того, чтобы новый объект, который будет выбран, контроллер должен быть сконфигурирован для -setSelectsInsertedObjects:YES ранее.

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

@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];  
} 
+0

Почему это вниз? Кажется, хорошо для меня. –

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