NSArrayController创建,修改然后选择一个新对象

时间:2010-01-25 13:33:44

标签: cocoa core-data nsarraycontroller

我的基于NSPersistentDocument的应用程序的主视图是一个表视图(绑定到NSArrayController),显示记录列表,在它下面有一个“添加记录”按钮。我希望按钮能够导致以下(假设是微不足道的)行为。

  1. 创建新对象
  2. 将一些默认值设置为新对象(存储在主文档中,不可全局使用)
  3. 将其添加到表格视图中。
  4. 以下是我尝试或解雇的事情:

    1. 使用NSArrayController“添加”操作 - 问题:不会返回新对象,并且实现被延迟,因此无法修改新创建的对象
    2. 覆盖数据类的init - 不起作用 - 我需要访问存储在文档类实例中的数据
    3. 子类NSArrayController并覆盖“newObject” - 再次 - 将无法工作,因为我需要访问存储在文档中的数据。
    4. 以下代码“几乎”有效:

      - (IBAction)newRecord:(id)sender
      {
          MyDataClass *newRecord = [recordsArrayController newObject];
      
          newRecord.setting1=self.defaultSetting1;
          newRecord.setting2=self.defaultSetting2;
          // ... etc...
          [recordsArrayController addObject:newRecord];
          [recordsTable scrollRowToVisible:[recordsTable selectedRow]];
          [newRecord release];    
      }
      
    5. 对于未保存的文档,此代码实际上运行良好。但是,如果我保存文档并重新打开它,则单击添加按钮会导致新记录在表格中显示两次。 显然“addObject”是多余的(尽管它在未保存的文档中工作正常)但没有它就不会选择新对象。

2 个答案:

答案 0 :(得分:2)

应该有效的简单案例:

MyDataClass *newRecord = [controller newObject];
// configure newRecord
[controller addObject:newRecord];
[newRecord release];

为了选择新对象,需要先为-setSelectsInsertedObjects:YES配置控制器。

但是,有一种我认为更合适的选择。像这样的子类NSArrayController(轻微的伪代码):

@interface MyRecordController : NSArrayController
@property id recordSetting1;
@property id recordSetting2;
@end

@implementation MyRecordController

@synthesize recordSetting1;
@synthesize recordSetting2;

- (id)newObject
{
    id result = [super newObject];
    newRecord.setting1 = self.recordSetting1;
    newRecord.setting2 = self.recordSetting2;
    return result;
}

@end

所以,你的代码变成了:

- (IBAction)newRecord:(id)sender
{
    recordsArrayController.recordSetting1 = self.defaultSetting1;
    recordsArrayController.recordSetting2 = self.defaultSetting2;
    [recordsArrayController add:self];    
}

答案 1 :(得分:1)

实际上,您需要做的就是修改代码以省略addObject:调用。要选择新对象,只需执行以下操作:

[recordsArrayController setSelectedObjects:[NSArray arrayWithObject:newObject]];
在致电swcrollRowToVisible:之前

。你是对的,addObject:电话不需要。正如您所见,它最终会在阵列控制器中结束两次。

此外,您无需致电[newRecord release]。文档说该对象由数组控制器保留。它现在没有失败,因为当你addObject:时,它会被第二次保留。