NSPredicate与NSFetchedResultsController获取所有数据存储,但限制某个匹配?

时间:2014-04-29 12:12:18

标签: ios uitableview core-data nspredicate nsfetchedresultscontroller

我不确定这是否可行 - 可能使用子查询 - 但是,我想设置一个获取请求,它将获取匹配某组属性的数据存储中的所有实体。很简单,但我还想限制符合另一组标准的对象数量。

与滚动我自己的数组和管理FRC工作得很好相比,我更愿意坚持使用NSFetchedResultscontroller。

我将使用一个例子,因为这与我一直在研究的项目有关,并且不想“放弃太多”。基本实体示例:

磁带

  • (字符串)名称
  • (关系)制造商
  • (bool)isTransparent
  • (bool)isEmpty

代码:

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Tape"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"manufacturer = %@", manufacturer];
request.predicate = predicate
request.sortDescriptors = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES  selector:@selector(caseInsensitiveCompare:)];

NSFetchedResultsController frc = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:moc sectionNameKeyPath:@"isTransparent" cacheName:nil];

FRC使用name按字母顺序排序,使用isTransparent标志来分隔各个部分(效果很好)。

商店中有多个标记有isEmpty标志的对象;但是,当显示给用户时,无论给定时间,我都只想显示一个标有isEmpty标志的文件。

因此,我们可能会有以下商店:

  • Alpha tape(isEmpty = 0,isTransparent = 1)
  • Beta磁带(isEmpty = 0,isTransparent = 0)
  • Gamma tape(isEmpty = 1,isTransparent = 1)
  • Delta tape(isEmpty = 1,isTransparent = 0)

从当前谓词中,我们得到一个这样的表:

  • Alpha tape(isEmpty = 0,isTransparent = 1)
  • Gamma tape(isEmpty = 1,isTransparent = 1)
  • 分节
  • Beta磁带(isEmpty = 0,isTransparent = 0)
  • Delta tape(isEmpty = 1,isTransparent = 0)

我想知道的是,是否可以为表视图获取类似内容(与FRC匹配):

  • Alpha tape(isEmpty = 0,isTransparent = 1)
  • Gamma tape(isEmpty = 1,isTransparent = 1)
  • 分节
  • Beta磁带(isEmpty = 0,isTransparent = 0)

因此,表视图由isTransparent标志划分,但只显示一个标有isEmpty标志的对象。

希望以下附加代码有所帮助。这就是我使用数组的方法(注意快速和脏):

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Tape"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"manufacturer = %@", manufacturer];
request.predicate = predicate
request.sortDescriptors = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES  selector:@selector(caseInsensitiveCompare:)];

BOOL foundEmpty = NO;
NSMutableArray *sectionOne = [[NSMutableArray alloc] init];
NSMutableArray *sectionTwo = [[NSMutableArray alloc] init];

NSArray *result = [self.managedObjectContext executeFetchRequest:request error:nil];
for (Tape *tape in result) {
    if ( tape.isEmpty.boolValue && !foundEmpty && tape.isTransparent.boolValue ) {
        // only include one isEmpty object
        [sectionOne addObject:tape];
        foundEmpty = YES;

    } else if ( tape.isEmpty.boolValue && !foundEmpty && !tape.isTransparent.boolValue ) {
        // only include one isEmpty object
        [sectionOne addObject:tape];
        foundEmpty = YES;

    } else if ( tape.isTransparent.boolValue && !tape.isEmpty.boolValue ) {
        // always include non-isEmpty objects
        [sectionOne addObject:tape];

    } else if ( !tape.isEmpty.boolValue ) {
        // always include non-isEmpty objects
        [sectionTwo addObject:tape];

    }
}

NSArray self.dataSource = @[sectionOnce, sectionTwo];

2 个答案:

答案 0 :(得分:0)

尝试以下谓词

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(manufacturer = %@) AND (NOT (isTransparent = 0 AND isEmpty = 1)))", manufacturer];

以上代码与制造商一起检查isEmpty为YES,

答案 1 :(得分:0)

很简单,您需要做的就是为表委托方法添加一点逻辑。目前,您将从FRC返回部分行数。相反,对于相应的部分,请返回:

MIN(1, rowCountFromFRC)

这样如果没有行,则不会显示任何行,但如果有,则会显示最多1行。