一种廉价的黑客方法:
添加一个名为nameOfRelevantB
object的类别方法A
,设置myC
为全局(或者,可能将其传递给 A 上的类方法,将其存储到文件本地静态),然后设置nameOfRelevantB
为sectionNameKeyPath
.NSFetchedResultsController
nameOfRelevantB
将找到与提供的 C 匹配的 B 并将其返回。
明显的缺点是您一次只能拥有一个相关的 C。
您可以通过制定一条规则来改善这一点,即在您的应用程序中,获取的结果控制器与队列或线程具有一对一的关系,并将相关的 C 存储为队列或线程上下文,但UITableViewDataSource
无论如何您都需要按顺序编写手册将结果移植回主队列/线程。
如果您要编写一个自定义数据源,您不妨将其NSFetchedResultsControllerDelegate
设置为根据自己的意愿将事物分解为多个部分,从而避免使用 [file static] 全局。
更彻底的解决方案:
您可以覆盖valueForUndefinedKey:
您的NSManagedObject
子类并将相关的 CobjectID
直接放入关键路径中。这样做是明确安全的,因为托管对象 ID 具有 aURIRepresentation
和NSURL
提供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 就会保持不变。