代码之家  ›  专栏  ›  技术社区  ›  Eyal Redler

nsarraycontroller创建、修改然后选择新对象

  •  1
  • Eyal Redler  · 技术社区  · 15 年前

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

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

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

    1. 使用nsarraycontroller“add”操作-问题:不会返回新对象,并且实现被延迟,因此无法修改新创建的对象
    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];    
      }
      

    对于未保存的文档,此代码实际上工作得很好。但是,如果我保存文档并重新打开它,然后单击“添加”按钮将导致新记录在表中显示两次。 显然,“addobject”是多余的(虽然它在未保存的文档中工作得很好),但是没有它,新对象就没有被选中。

    2 回复  |  直到 15 年前
        1
  •  2
  •   Mike Abdullah    15 年前

    应该有效的简单案例:

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

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

    但是,有一个我认为更合适的选择。子类nsarraycontroller like so(轻微的伪代码):

    @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
  •  1
  •   Alex    15 年前

    实际上,您所需要做的就是修改代码以忽略 addObject: 打电话。要选择新对象,请执行以下操作:

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

    在你打电话给 swcrollRowToVisible: . 你说得对 AdObjult: 不需要呼叫。如您所见,它在阵列控制器中结束了两次。

    而且,你不需要打电话 [newRecord release] . 文档中说该对象由数组控制器保留。它现在没有失败,因为它是第二次被保留,当你这样做的时候 AdObjult: .