核心数据:使用NSFetchRequest当结果类型设置为NSDictionaryResultType时,有没有办法获取获取的属性

时间:2012-07-12 14:11:42

标签: ios cocoa-touch cocoa core-data

我有一个使用两个独立核心数据存储的应用程序。一个用于用户数据,一个用于只读内容数据。为了在它们之间创建关系,当然禁止使用关系,因此对内容存储的引用由id管理。

在大多数情况下,这种方法很好,但对于某些特定的提取,这是很困难的。

采用以下示例:假设我有一部有几百部电影的应用程序(每个电影都存储在只读存储中),每当用户观看一部电影时,就会在可写用户存储中创建一条记录。我可能会将我的模型设置为一个名为Movie的实体,另一个名为MovieHistory。

电影有: 一个名为identifier(NSNumber)的属性。

MovieHistory有: 一个名为movieIdentifier的属性(对Movie的跨店参考), 一个viewDate属性(NSDate), 和一个获取属性'movie',目标设置为Movie,谓词为(SELF.identifier == $ FETCH_SOURCE.movi​​eIdentifier)。

说我现在想观看最后10部电影,没有重复(如果我观看我以前看过的电影应该跳到列表的顶部)。我希望能够使用以下代码:

NSError *error = nil;

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName: @"MovieHistory"];

NSSortDescriptor *dateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"viewDate" ascending:NO];

NSEntityDescription* entity = [NSEntityDescription entityForName:@"MovieHistory" inManagedObjectContext: moc];
NSAttributeDescription* movieIdentifierDesc = [entity.attributesByName objectForKey:@"movieIdentifier"];
NSFetchedPropertyDescription *movieDesc = [entity.propertiesByName objectForKey:@"movie"];

[request setFetchLimit: limit];
[request setSortDescriptors: [NSArray arrayWithObject: dateDescriptor]];
[request setPropertiesToFetch:[NSArray arrayWithObjects: movieIdentifierDesc, movieDesc, nil]];
[request setPropertiesToGroupBy:[NSArray arrayWithObject: movieIdentifierDesc]];
[request setResultType:NSDictionaryResultType];

NSArray *results = [moc executeFetchRequest: request error: &error];

if(error != nil)
    NSLog(@"Error fetching last viewed movies: %@", error);

return results;

此代码抛出一个异常,指出fetched属性('MovieHistory'中的'movie')是在这种情况下使用的无效属性。使用NSDictionaryResultType时,不能使用获取的属性。但是,您也不能使用setPropertiesToGroupBy:不返回类型为NSDictionaryResultType。我需要分组才能按日期排序并删除重复的电影。

当我从发送到setPropertiesToFetch:的数组中删除fetched属性时,它工作正常。但当然,我必须在一个循环中逐个拉出每个MovieRecord。

完成我想要做的事情的最佳方法是什么?有没有办法做到这一点,而不必诉诸获取ID,然后逐个循环结果?

谢谢,

1 个答案:

答案 0 :(得分:0)

然而,我没有完全按照你的整篇文章......

您可以发出两个单独的抓取操作。第一个从该数据库中获取MovieHistory对象。

将所有电影标识符放入集合中,然后使用IN关键字在电影数据库上获取。

NSPredicate *moviePredicate = [NSPredicate predicateWithFormat: @"identifier IN %@", allMovieIdentifiers];

它不像其他一些解决方案那么优雅,但它易于编写,更重要的是,易于阅读,理解和更改。记住首先为程序员优化。