Изменение управляемого объекта, выбранного из NSArrayController - PullRequest
0 голосов
/ 03 марта 2011

ОК, поэтому я собираюсь создать приложение для Mac OS X с использованием Core Data.

Основная схема такова, что есть главное окно, содержащее NSTableView, в котором отображается краткое описание.всех объектов, управляемых приложением;сущности простые, содержащие несколько полей, таких как заголовок, дата и примечания.Главное окно содержит команды для добавления, удаления и изменения записей.При добавлении или изменении записи приложение отображает новое окно, в котором есть все свойства этого объекта, доступные для редактирования.

Окно редактора находится в собственном .nib и управляется подклассом NSWindowControllerи загружается через вызов [[SUBCLASS alloc] initWithWindowNibName:].Редактируемые поля в этом окне связаны с NSObjectController, который будет управлять одной записью из списка.Этот контроллер не связан ни с чем из пера;когда этот контроллер загружается, его значения managedObjectContext и content устанавливаются в контексте основного объекта и редактируемой сущности соответственно.

Итак, добавление объекта работает отлично и работает так:

NSEntityDescription *entityDesc = [[self.managedObjectModel entitiesByName] objectForKey: @"LogEntryEntity"];
LogEntryEntity *entry = (LogEntryEntity *) [[NSManagedObject alloc] initWithEntity: entityDesc
    insertIntoManagedObjectContext: self.managedObjectContext];
LogEditorController *editor = [[LogEditorController alloc] initWithWindowNibName: @"LogEditorWindow"
    logEntry: entry];
entry.date = [NSDate dateOneHourAgoTo30Minutes];
[editor setSaveHandler: ^(LogEditorController *c)
 {
     NSError *error = nil;
     if (![self.managedObjectContext save: &error])
         NSLog(@"Failed to save object: %@", error);
     [self.logTableView reloadData];
 }];
[entry release];
[editor loadWindow];
[editor showWindow: self];

Удаление также работает:

NSIndexSet *selectedIndexes = [self.logTableView selectedRowIndexes];
if ([selectedIndexes count] == 0)
    return;
[self.logArrayController removeObjectsAtArrangedObjectIndexes: selectedIndexes];
if (![self.managedObjectContext save: &error])
    NSLog(@"error saving: %@", error);

Но когда я иду редактировать выбранную запись:

NSIndexSet *selectedIndexes = [self.logTableView selectedRowIndexes];
if ([selectedIndexes count] != 1)
    return;

LogEntryEntity *entry = (LogEntryEntity *) [[self.logArrayController arrangedObjects] objectAtIndex: [selectedIndexes firstIndex]];
LogEditorController *editor = [[LogEditorController alloc] initWithWindowNibName: @"LogEditorWindow"
    logEntry: entry];
[editor setSaveHandler: ^(LogEditorController *c)
 {
     NSError *error = nil;
     if (![self.managedObjectContext save: &error])
         NSLog(@"error saving: %@", error);
 }];
[editor loadWindow];
[editor showWindow: self];

Что здесь происходит, однако, это когдаПоявится окно, поля заполнены содержимым правильной записи. Но , сразу после того, как все поля устанавливаются на значения некоторой другой записи (возможно, не случайно, она устанавливается на поле с наименьшим objectID из всех объектов), иКогда я закрою окно, я могу подтвердить, что значение content значения NSObjectController изменилось на эту другую сущность.Когда я впервые установил content, я подтвердил, что это тот, который я хочу редактировать.

Что здесь происходит?Я имею в виду, ясно, что я делаю что-то не так, но я не могу понять, что.

1 Ответ

0 голосов
/ 03 марта 2011

Я не вижу из этого кода, как окно editor может переключать объекты LogEntryEntity, если у вас нет другого кода или вы неправильно связали окно редактора. Вы передаете определенный объект, а не массив объектов, так как же окно editor может найти другие объекты для некорректного отображения?

Я бы предложил удалить приведение с этой линии:

LogEntryEntity *entry = (LogEntryEntity *) [[self.logArrayController arrangedObjects] objectAtIndex: [selectedIndexes firstIndex]];

... потому что если по какой-то причине объект, возвращаемый из массива, не является действительным LogEntryEntity объектом, вы никогда не узнаете. Это может быть другой управляемый объект или что-то еще полностью. Приведения в Objective-C очень мощные, и компилятор, конечно, доверяет им неявно.

...