我正在iPhone上创建一个想法,但我正处于SQLite与CoreData的十字路口。主要原因是我似乎无法弄清楚如何对核心数据进行分组。
基本上我想显示按用户名分组的最新项目。在SQL语句中执行起来非常简单,但我无法在核心数据中使用它。我想,因为我正在开始一个新的应用程序,我不妨尝试使核心数据工作,但这部分是一个主要的障碍。
我在我的fetchrequest中添加了一个谓词,但这只给了我最近添加的单个记录,而不是每个用户最近添加的记录。
此时数据模型非常基础。它使用以下字段: username(字符串),post(字符串),created(datetime)
长话短说,CoreData可以使用这些类型的查询吗?我想如果SQLite在幕后,必须要有一些方法来实现它。
答案 0 :(得分:16)
首先,不要将Core Data视为另一种做SQL的方式。 SQL不是Core Data的“幕后”。核心数据处理对象。实体描述不是表,实体实例不是记录。使用Core Data进行编程与SQL无关,它只是将SQL用作几种可能类型的持久存储之一。你不直接处理它,也不应该用SQL术语来考虑核心数据。
那种方式就是疯狂。
你需要喝很多龙舌兰酒并反复冲击头部,直到你忘记了所有关于SQL的知识。否则,您最终会得到一个对象图,它只是一个大的电子表格。
有多种方法可以在Core Data中实现您的目标。通常,您将使用复合谓词构造fetch,该谓词将返回特定用户在特定日期范围内的所有帖子。获取结果控制器对此尤其方便。
最直接的方法是将对象图设置为:
UserEntity
--Attribute username
--Relationship post <-->> PostEntity
PostEntity
--Attribute creationDate
--Attribute content
-- Relationship user <<--> UserEntity
然后在你的UserEntity类中有一个像这样的方法:
- (NSArray *) mostRecentPost{
NSPredicate *recentPred=[NSPredicate predicateWithFormat:@"creationDate>%@", [NSDate dateWithTimeIntervalSinceNow:-(60*60*24)]];
NSSet *recentSet=[self.post filteredSetUsingPredicate:recentPred];
NSSortDescriptor *dateSort=[[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];
NSArray *returnArray=[[recentSet allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObject:dateSort]];
return returnArray;
}
如果您想要按日期排序的特定用户的最新帖子列表,请致电:
NSArray *arrayForDisplay=[aUserEntityClassInstance mostRecentPost];
编辑:
...我只是传递每个帖子块 数据(content,creationDate)到 发布实体?我也通过了 邮政实体的用户名?如何 用户实体知道何时创建 新用户?
让我伪代码吧。您有两个定义userObj和postObj实例的类。当有新帖发布时,您:
Parse inputPost for a user;
Search existing userObj for that name;
if userObj with name does not exist
create new userObj;
set userObj.userName to name;
else
return the existing userObj that matches the name;
Parse inputPost for creation date and content;
Search post of chosen userObj;
if an exiting post does not match content or creation date
create new postObj
set postObj.creationDate to creation date;
set postObj,content to content;
set postObj.user to userObj; // the reciprocal in userObj is created automatically
else // most likely ignore as duplicate
你有单独的userObj和postObj,因为虽然每个帖子都是唯一的,但每个用户可能有很多帖子。
要掌握的重要概念是您处理对象即封装的数据和逻辑实例。这不仅仅是db中的行和列。例如,您可以编写托管对象子类,其中单个实例可以决定是否与另一个类的实例形成关系,除非达到该对象的特定内部状态。 dbs中的记录没有那种逻辑或自治。
掌握使用数据模型的对象图的最佳方法是不仅忽略db而且忽略Core Data本身。相反,开始编写一个小型测试应用程序,您可以在其中手动编写所有数据模型类。它不必详细说明每个类的几个属性和某种类型的引用到另一个类。考虑如何管理将数据解析到每个类,将类和它们的数据链接在一起,然后将其取出。手动执行一次或两次,对象图的性质变得显而易见。
答案 1 :(得分:1)
还有其他一些注意事项可能会使SQLite存储向SQLite与Core Data的方向做出决定。在阅读一篇好文章blog post on the subject时,我发现自己点头同意。我找到了完全相同的东西(因此我将高性能的应用程序从Core Data中移开):“核心数据是正确的答案,除非它不是......”
这是一项伟大的技术,但一种尺寸绝对不适合所有。
答案 2 :(得分:0)
如果'posts'是用户的NSSet,您可以使用谓词获取最后一篇文章:
NSDate *lastDate = [userInstance valueForKeyPath:@"@max.date"];
NSSet *resultsTemp = [setOfPosts filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"fecha==%@", lastDate] ];
resultsTemp set将包含一个Post类型的对象,它具有最新的日期。