2

我有一个看起来像这样的模型:

在此处输入图像描述

在代码中,我强制要求虽然 A 可以有多个 B,但每个 C 只有一个 B。

我想要做的是列出所有给定C的As,按B分组。现在,如果我从我的C开始,得到所有B的集合,然后得到所有As的集合,这是相当简单的每个 B。

我想做的是使用 NSFetchedResultsController 列出 As。我可以使用“ANY bc MATCHES myC”按 C 过滤它们,但我看不到如何将它们按正确的 B 分组。

换句话说,由于一个 A 有很多 B,我如何确定哪个是属于我的 C 的,并在 NSFetchedResultsController 中使用它?这甚至可能吗?

4

1 回答 1

1

一种廉价的黑客方法:

添加一个名为nameOfRelevantBobject的类别方法A,设置myC为全局(或者,可能将其传递给 A 上的类方法,将其存储到文件本地静态),然后设置nameOfRelevantBsectionNameKeyPath.NSFetchedResultsController

nameOfRelevantB将找到与提供的 C 匹配的 B 并将其返回。

明显的缺点是您一次只能拥有一个相关的 C。

您可以通过制定一条规则来改善这一点,即在您的应用程序中,获取的结果控制器与队列或线程具有一对一的关系,并将相关的 C 存储为队列或线程上下文,但UITableViewDataSource无论如何您都需要按顺序编写手册将结果移植回主队列/线程。

如果您要编写一个自定义数据源,您不妨将其NSFetchedResultsControllerDelegate设置为根据自己的意愿将事物分解为多个部分,从而避免使用 [file static] 全局。

更彻底的解决方案:

您可以覆盖valueForUndefinedKey:您的NSManagedObject子类并将相关的 CobjectID直接放入关键路径中。这样做是明确安全的,因为托管对象 ID 具有 aURIRepresentationNSURL提供absoluteString。然后每个 A 可以从键路径中获取字符串 URI,询问其上下文的持久存储协调器managedObjectIDForURIRepresentation,然后询问上下文existingObjectWithID:error:以获取相关的 C。一旦它有了 C,它就可以从适当的 B 返回标题。

在没有任何类型的全局状态的情况下,这将实现您想要的。你也可以NSFetchedResultsController直接使用,给它一个可以确定部分的关键路径。

所以,例如(直接在这里输入,未经测试)

// get a URI for the relevant myC and prefix it with an '@'
// so that it's definitely clearly not an ordinary property
fetchedResults.sectionNameKeyPath = 
        [NSString stringWithFormat:@"@%@", 
              [[myC.objectID URIRepresentation] absoluteString]];

... in your subclass for A ...

- (id)valueForUndefinedKey:(NSString *)key
{
    // check that the key begins with the magic '@' symbol
    if(![key length] || [key characterAtIndex:0] != '@')
        return [super valueForUndefinedKey:key];

    // get the original URL
    NSString *URLString = [key substringFromIndex:1];
    NSURL *URL = [NSURL URLWithString:URLString];

    // transform the URL into the relevant instance of C
    NSManagedObjectID *objectID = [self.context.persistentStoreCoordinator
                  managedObjectIDForURIRepresentation:URL];
    NSError *error = nil;
    MyCClass *myC = [self.context existingObjectWithID:objectID error:&error];

    // check that we got an appropriate instance and didn't
    // generate an error
    if(!myC || error) return [super valueForUndefinedKey:key];

    /*
        code here to find the appropriate B and return a suitable title
    */
}

主要需要注意的是,对象 ID 以及 URI 可能会在对象的初始创建和第一次保存之间发生变化。如果您已经保存了上下文,那么只要对象在商店中,对象 ID 就会保持不变。

于 2012-11-20T23:02:51.403 回答