1

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

  1. 创建一个新对象
  2. 为新对象设置一些默认值(存储在主文档中,全局不可用)
  3. 将其添加到表视图中。

以下是我尝试或拒绝的事情:

  1. 使用 NSArrayController "add" 动作 - 问题:不会返回新对象并且实现被延迟所以不可能修改新创建的对象
  2. 覆盖数据类的初始化 - 不起作用 - 我需要访问存储在文档类实例中的数据
  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];    
    }
    

对于未保存的文档,此代码实际上运行良好。但是,如果我保存文档并重新打开它,然后单击添加按钮会导致新记录在表中显示两次。显然“addObject”是多余的(尽管它在未保存的文档中工作正常)但没有它,新对象不会被选中。

4

2 回答 2

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];    
}
于 2010-01-25T18:49:13.993 回答
1

Really, all you need to do is modify your code to omit the addObject: call. To make your new object selected, just do this:

[recordsArrayController setSelectedObjects:[NSArray arrayWithObject:newObject]];

before you do your call to swcrollRowToVisible:. You're right that the addObject: call is unneeded. As you've seen, it's ending up in the array controller twice.

Also, you won't need to call [newRecord release]. The documentation says the object is retained by the array controller. It's not failing now because it's being retained a second time when you do addObject:.

于 2010-01-25T14:27:03.520 回答