Справочная информация:
В моем приложении я специально нацелился на Mac OS X Lion. Эта проблема связана с базовыми данными, NSPopover
и дочерним NSManagedObjectContext
(созданным с использованием нового свойства parentContext NSManagedObjectContext
).
У меня есть таблица NSManagedObjects
класса "Местоположение". Есть кнопка Add, которая вызывает addLocation: и если дважды щелкнуть строку таблицы, я вызываю tableViewDoubleClick:.
В любом случае я создаю новый NSManagedObjectContext
и устанавливаю его родительский контекст в контекст документа. Затем я либо создаю новое местоположение в этом контексте, либо выбираю местоположение, которое нужно отредактировать, из временного контекста. Я установил для свойства popOverppedObject указанное местоположение. Если я отменю поповер, ничего не сохранится. Если пользователь нажимает кнопку «Сохранить» во всплывающем окне, я просто вызываю сохранить: во временном контексте, и изменения переносятся в основной контекст.
addLocation:
- (IBAction)addLocation:(id)sender
{
LocationEditViewController *popupController = [[[LocationEditViewController alloc] init] autorelease];
popupController.title = @"Add New Location";
NSManagedObjectContext *tempContext = [[[NSManagedObjectContext alloc] init] autorelease];
tempContext.parentContext = self.document.managedObjectContext;
Location *tempLocation = [NSEntityDescription insertNewObjectForEntityForName:@"Location" inManagedObjectContext:tempContext];
popupController.representedObject = tempLocation;
popupController.managedObjectContext = tempContext;
[popupController.popover showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMaxYEdge];
}
tableViewDoubleClick:
- (void)tableViewDoubleClick:(id)sender
{
NSInteger selectedRow = [self.table selectedRow];
if (selectedRow != -1)
{
NSRect rectOfSelectedRow = [self.table rectOfRow:selectedRow];
LocationEditViewController *popupController = [[[LocationEditViewController alloc] init] autorelease];
popupController.title = @"Edit Location";
Location *locationToEdit = [self.locationController.selectedObjects objectAtIndex:0];
NSManagedObjectContext *tempContext = [[[NSManagedObjectContext alloc] init] autorelease];
tempContext.parentContext = self.document.managedObjectContext;
Location *tempLocation = (Location *)[tempContext fetchObjectEqualTo:locationToEdit]; // Custom fetch helper method
popupController.managedObjectContext = tempContext;
popupController.representedObject = tempLocation;
[popupController.popover showRelativeToRect:rectOfSelectedRow ofView:sender preferredEdge:NSMaxXEdge];
}
}
Вот проблема, которую я хотел бы объяснить:
Текстовые поля в всплывающем окне связаны с представленным объектом всплывающего окна через привязки в кончике. Они прекрасно работают с новым объектом (addLocation :).
Если Location является существующим объектом (tableViewDoubleClick :), привязки работают достаточно хорошо, чтобы предварительно заполнить поля свойствами Location. Однако изменение текста в полях вообще не изменяет свойства местоположения. Когда во всплывающем окне была нажата кнопка «Сохранить», я попытался зарегистрировать свойства местоположения перед сохранением временного контекста. Если это существующий объект, все, что я ввожу в поля, не отражается в свойствах Location - как будто привязки взаимодействуют только в одном направлении.
Мой обходной путь: Я обнаружил, что если я пропущу привязки и просто вручную установлю в свойствах Location значения в текстовых полях перед сохранением, изменения вступят в силу.
- (IBAction)popoverSave:(id)sender
{
// These two methods always work. But if I remove these and use bindings instead, it only works for NEW Locations.
[(Location *)self.representedObject setLabel:self.labelField.stringValue];
[(Location *)self.representedObject setLocation:self.locationField.stringValue];
NSLog(@"representedObject = %@", self.representedObject);
NSError *error = nil;
[self.managedObjectContext save:&error];
[self.popover close];
}
Мне бы очень хотелось знать , почему это так, на тот случай, если я действительно что-то делаю не так.
Спасибо!