将核心数据对象组织成部分

时间:2011-08-29 09:30:20

标签: iphone objective-c ios core-data

我有以下数据模型:

managed object structure

打开文档后,我想列出UITableView中基础对象的图层(作为部分)。 我已通过以下方式实现了获取的结果控制器:

- (NSFetchedResultsController *)fetchedResultsController
{
    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }

    // Create the fetch request for the entity
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"DB_Layer" 
        inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size
    [fetchRequest setFetchBatchSize:10];

    // Sort by stacking order, descending
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
        initWithKey:@"stackingOrder" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];

    // Create the fetched results controller, and set this controller to be the delegate
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] 
        initWithFetchRequest:fetchRequest 
        managedObjectContext:managedObjectContext 
        sectionNameKeyPath:nil cacheName:@"Layer"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    // Fetch the results into the fetched results controller
    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return fetchedResultsController;
}

问题在于,这为我提供了所有图层的列表(甚至是属于其他文档的图层)。 我相信我应该使用NSPredicate缩小搜索范围,但我不确定如何。

我需要的是:

  • DB_Layer个对象组成的部分列表(我不确定在哪里可以指定将结果分组的内容)
  • 每个部分包含相应图层的对象/组。

编辑:

根据Richard Casey的回答,我现在可以获取图层列表,但它需要我检索所有 DB_Shape个对象(甚至属于其他文档的对象),并过滤它们与谓词。 这是一个很大的性能影响。

我真正想要的是另一种方式:

  • 将当前文档传递给NSFetchedResultsController
  • 检索相关对象,为每个DB_Layer创建一个部分 对象,
  • 列出相应的 - 分组(DB_Group)或分开 (DB_Shape)部分内的对象。

4 个答案:

答案 0 :(得分:2)

你是对的。要列出特定文档的图层,可以使用NSPredicate。

以下代码(在创建NSFetchedResultsController之前添加)应该这样做。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"document.name == %@",docName];
[fetchRequest setPredicate:predicate];

上述代码中的docName变量是您要列出的文档的名称属性。

创建NSFetchedResultsController时,sectionKeyNamePath参数指定用于为tableview生成组的属性。如果要按相应的层列出对象/组,您可能希望对DB_Shape实体运行NSFetchRequest,然后对sectionKeyNamePath使用@“layer.name”。

希望这有帮助!

答案 1 :(得分:2)

不完全是您问题的答案,但如果您手头有一个特定的DB_Document对象,那么您不必提取您只需要询问该对象的layer关系的内容,然后从那里开始

这是建立关系的重点。您已经知道了所需的对象,并且没有过滤整个持久性存储的形式。

答案 2 :(得分:2)

  

我真正想要的是另一种方式:

     
      
  • 将当前文档传递给NSFetchedResultsController,
  •   
  • 检索相关对象,为每个DB_Layer对象创建一个部分,
  •   
  • 列出相应的 - 在该部分中分组(DB_Group)或单独(DB_Shape)对象。
  •   

NSFetchResultsController只能返回一种类型的实体。因此,您无法使用当前模型列出DB_GroupDB_Shape个实体。 DB_Group实体与DB_Shape共享所有属性,因此您可以将DB_Shape设为DB_Group的子实体。

这种方式DB_Layer只有一对多的DB_Group关系,恰好也包含了形状。然后您获取请求:

  • 获取DB_Group个实体。
  • DB_Layer分组。
  • 使用基于图层DB_Document的谓词进行过滤。

对于演示文稿,如果您需要组和形状的不同视图类型,请使用isKindOfClass:

答案 3 :(得分:0)

不确定DB_Layer对象的结构是什么样的,但您可以做的是修改NSFetchedResultsController初始化,如下所示,以指定要在其中创建部分的DB_layer中的字段。例如,如果您的核心数据对象中有一个名为“field1”的字段要对结果进行分区,则更新sectionNameKeyPath应为您创建部分:

// Create the fetched results controller, and set this controller to be the delegate
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] 
    initWithFetchRequest:fetchRequest 
    managedObjectContext:managedObjectContext 
    **sectionNameKeyPath:@"field1"** cacheName:@"Layer"];

使用谓词会过滤您的结果 - 不确定您的目标是什么。上面的代码段应该根据“field1”将结果分组到各个部分。