3

我有一个核心数据模型: ParentObject <--->> ChildObject

两者ParentObject都有ChildObject一个属性levelNumber

typedef enum {
    Primary,
    Secondary,
    Tertiary
} LevelNumber;

我还有一种方法可以在 ParentObject 和 childObject 中将级别编号从 int 转换为 string:

-(void) levelString
{
    switch(self.levelNumber)
   {
      case Primary: return @"Primary";
      case Secondary: return @"Secondary";
      case Tertiary: return @"Tertiary";
      default: return @"Error";

   }

}

现在我在一个表视图中有一个 FetchedResultsController,它列出了ParentObject. 我想在部分名称中获得的是:

  • 如果ParentObjectSecondaryTertiary,则将部分名称显示为SecondaryTertiary
  • 如果ParentObjectPrimaryChildObjectsSecondary或中的任何一个Tertiary,则将部分名称显示为SecondaryTertiary
  • 如果 theParentObject和 all the ChildObjectsare Primary,则将部分名称显示为Primary

如果我只需要查看 的 ,它就非常简单levelNumberParentObject类似于以下内容-

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ParentObject"];
NSSortDescriptor *levelNumSD = [NSSortDescriptor sortDescriptorWithKey:@"levelNumber" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObjects:levelNumSD, nil];

self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                    managedObjectContext:myContext
                                                                      sectionNameKeyPath:@"levelString"
                                                                               cacheName:nil];

我知道 FRC 中的限制是 SortDescriptor 的结果应该以与希望显示的顺序相同的顺序返回结果。我怎样才能在ChildObject这里合并支票。它会是一种新的 SortDescriptor,还是别的什么?

4

1 回答 1

3

看看 Apple 的示例代码DateSectionTitles,它解释了如何将日期作为部分,并且您也可以使用它。您管理的字符串的实际显示,titleForSection但您在数据库中保留了一个“原始”且可排序的属性,称为sectionIdentifier.

在您的特定情况下,部分标识符就像levelNumber简单地通过返回levelNumber所有孩子中的最高者来计算。

模式如下:

-(NSString*)sectionIdentifier {
   [self willAccessValueForKey:@"sectionIdentifier"];
   NSNumber *tmp = [self primitiveSectionIdentifier];
   [self didAccessValueForKey:@"sectionIdentifier"];

   if (!tmp) {
      NSNumber *childrenMax = [self valueForKeyPath:@"@max.children.levelNumber"];
      tmp = childrenMax.intValue > self.levelNumber.intValue ?
            childrenMax : self.levelNumber;
      [self setPrimitiveSectionIdentifier:tmp];
   }

   return tmp;
}

如果实体发生变化,不要忘记重置它。

-(void)setLevelNumber:(NSNumber)newNumber {
   [self willChangeValueForKey:@"levelNumber"];
   [self setPrimitiveLevelNumber:newNumber];
   [self willChangeValueForKey:@"levelNumber"];

   [self setPrimitiveSectionIdentifier:nil];
}

最后,确保相关数据发生变化时失效:

+(NSSet*) keyPathsForValuesAffectingSectionIdentifier {
   return [NSSet setWithObject:@"levelNumber"];
}

要监视levelNumber任何孩子的变化,让父母倾听NSManagedObjectContextDidSaveNotification并查看是否有任何孩子在该保存中。

于 2013-06-30T07:47:38.767 回答