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

Posted

技术标签:

【中文标题】NSArrayController 创建、修改然后选择一个新对象【英文标题】:NSArrayController creating, modifying and then selecting a new object 【发布时间】:2010-01-25 13:33:44 【问题描述】:

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

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

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

    使用 NSArrayController "add" 操作 - 问题:不会返回新对象并且实现被延迟,因此无法修改新创建的对象 覆盖数据类的初始化 - 不起作用 - 我需要访问存储在文档类实例中的数据 子类 NSArrayController 并覆盖“newObject” - 再次 - 将不起作用,因为我需要访问存储在文档中的数据。

    以下代码“几乎”工作:

    - (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”是多余的(尽管它在未保存的文档中工作正常)但没有它,新对象不会被选中。

【问题讨论】:

【参考方案1】:

应该可以工作的简单案例:

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

【讨论】:

【参考方案2】:

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

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

在您致电swcrollRowToVisible: 之前。你是对的,不需要addObject: 电话。如您所见,它在数组控制器中结束了两次。

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

【讨论】:

错了,您需要致电[newRecord release]。使用 -newObject 创建它会使其保留计数为 +1。 除了保留计数的参数之外,这个答案有效,并且比子类化 NSArray 更好。 谢谢,解决方案有效。关于“relaese”的评论确实不正确,newObject 为您提供了一个您需要释放的保留对象。 我的回复太仓促了。事实证明,这个解决方案行不通。 真的吗?因为我昨晚试过了,它对我有用。你想分享你的最新代码吗?

以上是关于NSArrayController 创建、修改然后选择一个新对象的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 NSArraycontroller 在可可上创建 NSFetchedresultController?

两个 NSArrayController 和一个关系(CoreData)

NSArrayController 的奇怪行为

如何使用 Core Data 设置 NSArrayController?

在另一个线程中使用来自 NSArrayController 的 NSManagedObjects

对支持 CoreData 的 NSArrayController 进行排序时遇到问题