【问题标题】:Filter NSFetchedResultsController to get only objects with some relationship过滤 NSFetchedResultsController 以仅获取具有某种关系的对象
【发布时间】:2014-03-13 15:47:54
【问题描述】:

我有两个实体,A 和 B,以及以下关系:

A -> B - 对许多

B -> A - 对一个

换句话说:A 可以有零个或多个 B,而 B 只能有一个 A。

我想使用 NSFetchedResultsController 在表格视图中显示我的 A 条目,但我想通过 A -> B 关系过滤结果。 为此,我有一个 UISegmentedControl,如果用户点击第一个片段,我只想显示与 B 至少有一个关系的 A 条目,如果点击第二个片段,我只想显示没有关系的条目与 B.

我正在使用 CoreData 的 NSManagedObject,所以我的 A 对象有一个 NSSet 属性,其中所有 B 条目都与 A 有关系。

这就是我实例化我的 NSFetchedResultsController 的方式:

    NSManagedObjectContext *context = self.managedObjectContext;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:"A" inManagedObjectContext:self.managedObjectContext];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:descriptorKey ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];
    [fetchRequest setEntity:entity];


    NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]
                                              initWithFetchRequest:fetchRequest
                                              managedObjectContext:context
                                              sectionNameKeyPath:controllerKey
                                              cacheName:nil];

    NSError *error;
    BOOL success = [controller performFetch:&error];

    if (success) {
        return controller;
    }

此代码获取所有 A 条目,我该如何制作该过滤器?

【问题讨论】:

  • 您的提取请求没有谓词。这就是您定义过滤器的地方。
  • 但是我怎样才能创建一个谓词来按关系过滤呢?我正在尝试验证 NSSet 计数,但到目前为止没有成功。

标签: ios objective-c uitableview core-data nsfetchedresultscontroller


【解决方案1】:

您需要在获取请求中添加谓词:

例如

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"B.@count == 0"];
[fetchRequest setPredicate:predicate];

这将过滤没有任何相关 B 对象的As。

【讨论】:

  • 工作就像一个魅力!我设置了谓词错误,我在做 [NSPredicate predicateWithFormat:@"B.count == 0"] 而不是 [NSPredicate predicateWithFormat:@"B.@count == 0"]。非常感谢!
【解决方案2】:

正如@Abizern 在 cmets 中提到的,您需要在您的NSFetchedResultsController 中添加一个NSPredicate。谓词类似于:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"b == %@", myVarReferenceToB]];

如果您在 B 中只有一个唯一标识符(我们称之为 identifier)而不是对象引用,您可以将其写为:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"b.identifier == %@", myVarReferenceToBIdentifier]];

这将生成您的过滤器。

每次用户更改分段控件时,您都需要重新构建提取,或者您需要在每个分段周围保留一个 NSFetchedResultsController

【讨论】:

  • 如果你要重建 fetch,并且 NSFetchedResultsController 使用缓存,记得调用 deleteCacheWithName:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多