Cocoa 修改从NSArrayController获取的托管对象

Cocoa 修改从NSArrayController获取的托管对象,cocoa,core-data,cocoa-bindings,Cocoa,Core Data,Cocoa Bindings,好的,我正在尝试使用核心数据构建一个MacOSX应用程序 基本布局是有一个主窗口,其中包含一个NSTableView,其中显示应用程序管理的所有对象的简要说明;实体很简单,包含几个字段,如标题、日期和注释。主窗口提供添加、删除和修改条目的命令。添加或修改条目时,应用程序将显示一个新窗口,其中包含该对象的所有属性可供编辑 编辑器窗口位于自己的.nib中,由NSWindowController的子类管理,并通过[[subclass alloc]initWithWindowNibName:]调用加载。

好的,我正在尝试使用核心数据构建一个MacOSX应用程序

基本布局是有一个主窗口,其中包含一个NSTableView,其中显示应用程序管理的所有对象的简要说明;实体很简单,包含几个字段,如标题、日期和注释。主窗口提供添加、删除和修改条目的命令。添加或修改条目时,应用程序将显示一个新窗口,其中包含该对象的所有属性可供编辑

编辑器窗口位于自己的.nib中,由NSWindowController的子类管理,并通过[[subclass alloc]initWithWindowNibName:]调用加载。此窗口中的可编辑字段绑定到NSObjectController,它将管理列表中的单个条目。此控制器不绑定到nib之外的任何内容;加载此控制器时,其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最小的一个,我可以在窗口关闭时确认NSObjectController的内容值已更改为不同的实体。当我第一次设置内容时,我已经确认它是我想要编辑的内容


这是怎么回事?我的意思是,很明显我做错了什么,但我不知道是什么。

从这段代码中,我看不出编辑器窗口如何切换LogEntryEntity对象,除非您有其他代码或错误地绑定了编辑器窗口。您传递的是一个特定对象,而不是一个对象数组,那么编辑器窗口如何找到要错误显示的其他对象呢

我建议从这一行中删除演员阵容:

LogEntryEntity *entry = (LogEntryEntity *) [[self.logArrayController arrangedObjects] objectAtIndex: [selectedIndexes firstIndex]];
。。。因为如果由于某种原因,从数组返回的对象不是实际的LogEntryEntity对象,您将永远不会知道。它可能是另一个managedObject或完全其他的东西。Objective-C中的强制转换功能非常强大,编译器当然会隐式信任它们