繁体   English   中英

NSFetchedResultsController:如何从实体的to-many关系中获取sectionName

[英]NSFetchedResultsController: How to get sectionName from to-many relationship of the entity

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

ParentObjectChildObject都具有属性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";

   }

}

现在我在tableview中有一个FetchedResultsController,它列出了ParentObject 我想在部分名称中得到的是:

  • 如果ParentObjectSecondaryTertiary ,则将节名称显示为SecondaryTertiary
  • 如果ParentObjectPrimary但任何ChildObjectsSecondaryTertiary ,则将节名称显示为SecondaryTertiary
  • 如果ParentObject和所有ChildObjects都是PrimaryChildObjects section name显示为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,还是其他什么?

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

在您的特定情况下,节标识符就像levelNumber一样,只需返回所有子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并查看其中是否存在任何子级。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM