0

チャット アプリに次のオブジェクトがあります (1 対多の関係)

@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 インスタンスをフェッチしようとしましたが、そのコンテキストで最新のエントリを実際に読み取る方法がわかりません。

4

1 に答える 1

0

OK、なんとか解決できました。私がしたことは、コンテキストに「lastMessage」オブジェクトを追加することです。これは、新しいメッセージごとに更新され続けます。次に、逆にされたlastMessage.timestampでソートされたコンテキストのリストを照会します。新しいメッセージは、コンテキスト内のlastMessageプロパティを更新します。これにより、イベントがトリガーされ、UIが自動的に更新されます。

于 2012-07-24T21:20:00.160 に答える