NSPredicate 用于集合中的最新项目

Posted

技术标签:

【中文标题】NSPredicate 用于集合中的最新项目【英文标题】:NSPredicate for latest item in a collection 【发布时间】:2012-07-19 22:07:13 【问题描述】:

我的聊天应用中有以下对象(具有一对多关系)

@interface ChatEntry : NSManagedObject
@property (nonatomic, retain) NSString * text;
@property (nonatomic, retain) NSDate * timestamp;
@property (nonatomic, retain) ChatContext *context;
@end

@interface ChatContext : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * userId;
@property (nonatomic, retain) NSSet *entries;
@end

每个对话 (ChatContext) 将该用户发送的所有消息分组(由 userId 字段唯一标识)。

我正在尝试显示一个对话列表,其中显示每个对话的最后一条消息(类似于 iMessage)。

我正在使用以下代码:

NSFetchRequest* request=[[NSFetchRequest alloc] initWithEntityName:@"ChatEntry"];
request.predicate=[NSPredicate predicateWithFormat:@"timestamp=context.entries.@max.timestamp"];
request.sortDescriptors=[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"timestamp" ascending:NO]];
m_chat=[[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:m_context sectionNameKeyPath:nil cacheName:@"chat"];
m_chat.delegate=self;

这工作正常,直到我收到一条新消息(使用 NSFetchedResultsChangeInsert)

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath

...

此时,我的表格视图中出现了另一个条目。提取控制器保留前一个条目(即使它的时间戳不再是最新的)。我不确定如何解决这个问题并强制控制器始终评估谓词。

或者,我尝试更改查询以获取 ChatContext 实例,但我不确定如何实际读取该上下文中的最新条目。

【问题讨论】:

在下面查看我的答案 【参考方案1】:

好的,我已经设法解决了。我所做的是将一个“lastMessage”对象添加到上下文中,我会不断更新每条新消息。然后我查询上下文列表,按反向 lastMessage.timestamp 排序。新消息会在其上下文中更新 lastMessage 属性 - 这会触发事件并自动更新 UI。

【讨论】:

以上是关于NSPredicate 用于集合中的最新项目的主要内容,如果未能解决你的问题,请参考以下文章

NSPredicate的使用

NSPredicate 和 NSArray

NSPredicate 用于从一对多关系中获取项目,不包括特定的相关实体

NSPredicate 不适用于 ios 中的过滤

NSPredicate 用于查询中的位置

NSPredicate 用于 NSFetchRequest 中的多个匹配项