修改从NSArrayController获取的托管对象

时间:2011-03-03 08:41:57

标签: cocoa core-data cocoa-bindings

好的,所以我正在使用Core Data构建Mac OS X应用程序。

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

编辑器窗口位于自己的.nib中,由NSWindowController的子类管理,并通过[[SUBCLASS alloc] initWithWindowNibName:]调用加载。此窗口中的可编辑字段绑定到NSObjectController,它将管理列表中的单个条目。这个控制器没有绑定到笔尖外的任何东西;加载此控制器时,其managedObjectContextcontent值分别设置为主对象上下文和正在编辑的实体。

因此,添加一个对象效果很好,并且工作方式如下:

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的{​​{1}}值已更改为该不同的实体。当我第一次设置NSObjectController时,我已经确认它是我要编辑的那个。

这里发生了什么?我的意思是,很明显我做错了什么,但我无法弄清楚是什么。

1 个答案:

答案 0 :(得分:0)

我没有从这段代码中看到editor窗口如何切换LogEntryEntity对象,除非你有其他代码或者错误地绑定了编辑器窗口。您传递的是特定对象而不是对象数组,因此editor窗口如何找到其他对象错误显示?

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

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

...因为如果由于某种原因从数组返回的对象不是实际的LogEntryEntity对象,你永远不会知道。它可能是另一个托管对象或完全不同的东西。在Objective-C中进行强制转换非常强大,编译器当然会隐含地信任它们。