gpt4 book ai didi

objective-c - 子上下文中与 NSManagedObject 的绑定(bind)仅适用于新对象

转载 作者:行者123 更新时间:2023-12-03 18:00:40 24 4
gpt4 key购买 nike

背景:

在我的应用程序中,我专门针对 Mac OS X Lion。此问题涉及 Core Data、NSPopover 和子 NSManagedObjectContext(通过使用 NSManagedObjectContext 的新 ParentContext 属性创建)。

我有一个“Location”类的NSManagedObjects表。有一个调用 addLocation: 的“添加”按钮,如果双击表格行,我会调用 tableViewDoubleClick:。

对于任何一种情况,我所做的都是创建一个新的 NSManagedObjectContext 并将其父上下文设置为文档上下文的父上下文。然后,我要么在该上下文中创建一个新位置,要么从临时上下文中获取要编辑的位置。我将弹出窗口的representedObject 属性设置为有问题的位置。如果我取消弹出窗口,则不会保存任何内容。如果用户单击弹出窗口中的“保存”按钮,我只需在临时上下文上调用 save: ,更改就会推送到主上下文。

添加位置:

- (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];

}
}

这是我想要解释的问题:

弹出窗口中的文本字段通过 Nib 中的绑定(bind)连接到弹出窗口的representedObject。这些与新对象(addLocation:)完美配合。

如果位置是现有对象 (tableViewDoubleClick:),则绑定(bind)可以很好地使用位置的属性预先填充字段。但是,更改字段中的文本根本不会改变位置的属性。单击弹出窗口中的“保存”按钮时,我尝试在保存临时上下文之前记录位置的属性。如果它是一个现有对象,则我在字段中输入的任何内容都不会反射(reflect)在位置的属性中 - 就好像绑定(bind)仅进行单向通信一样。

我的解决方法:我发现,如果我跳过绑定(bind)并在保存之前将位置的属性手动设置为文本字段中的值,则更改会生效。

- (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];
}

我真的很想知道为什么会出现这种情况,以防万一我真的做错了什么。

谢谢!

最佳答案

我认为很可能是这些台词中的 Actor :

[(Location *)self.representedObject setLabel:self.labelField.stringValue];
[(Location *)self.representedObject setLocation:self.locationField.stringValue];

...这使它们能够工作。如果是这样,那么您可能在绑定(bind)中的某个位置设置了 NSObject 或 NSManagedObject 作为类,而不是 Location 类。当绑定(bind)发送 Location 类特定消息时,例如将具有特定名称的属性设置给通用类,通用类会默默地忽略该消息。

顺便说一句,我会警告不要使用多个上下文而不是使用撤消 API。我看到很多人都这样陷入麻烦。回滚单个上下文比管理多个上下文更容易。

关于objective-c - 子上下文中与 NSManagedObject 的绑定(bind)仅适用于新对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7165927/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com