如何通过键和值获得对象

我有一个名为masterMessages的对象,里面充满了称为消息的对象。 每个消息对象有五个键:

  • OBJECTID
  • 发件人ID
  • 发件人名称
  • 邮件正文
  • 时间戳

基本上我现在正在做的是查询所有的消息发送到我的用户在这个对象称为masterMessages。 然后我使用:

self.senderIds = [masterMessages valueForKeyPath:@"@distinctUnionOfObjects.senderId"]; 

在名为senderIds的数组中获取所有不同的发件人ID(senderId)。 有了这个,我将填充我的对话表。 但我想填充发件人名称(senderName)而不是senderIds。 我只是这样做,以防两名用户有相同的名字。

我试图find:

  1. 我怎么说“get valueForKey:@”senderName“这个senderId

  1. 有没有更好的方式来填充我的对话表?

这是我的代码:

注意:即时通讯使用parse.com

  -(void)viewWillAppear:(BOOL)animated{ NSString *userId = [[PFUser currentUser] objectId]; PFQuery *query = [PFQuery queryWithClassName:@"lean"]; [query whereKey:@"recipientId" equalTo:userId]; [query orderByDescending:@"createdAt"]; [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { if (error) { NSLog(@"Error: %@ %@", error, [error userInfo]); } else { // We found messages! masterMessages = objects; NSLog(@"self.messages = %@", masterMessages); self.senderIds = [masterMessages valueForKeyPath:@"@distinctUnionOfObjects.senderId"]; NSLog(@"self.senderIds = %@", self.senderIds); [self.tableView reloadData]; } }]; } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Return the number of sections. return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. return [self.senderIds count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; NSLog(@"self.senderIds = %@", self.senderIds); NSString *senderDisplayName = [self.senderIds objectAtIndex:indexPath.row]; NSLog(@"sender = %@", senderDisplayName); cell.textLabel.text = senderDisplayName; return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { selectedId = [self.senderIds objectAtIndex:indexPath.row]; [self performSegueWithIdentifier:@"ShowMissionMessage" sender:self]; } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"ShowMissionMessage"]) { [segue.destinationViewController setHidesBottomBarWhenPushed:YES]; MissionChat *missionchatviewcontroller = (MissionChat *)segue.destinationViewController; missionchatviewcontroller.selectedId = selectedId; missionchatviewcontroller.masterMessages = masterMessages; } } 

在这个问题中有几个问题,一个是如何取消引用另一个线程上的 PFObjects。 这个问题的其余部分是关于如何使用parse对象来构build一个支持tableview的数据源,以及如何从相关的对象中获取信息。

从(b)开始,更难:有关联对象的方法有几种。 你select一个包含相关对象ID的stringtypes的列是直观的(特别是如果你有一个SQL背景的话),但是最不可取的是。 模拟一对一或小一对多关系的更好(最佳)方式是使用指针(或者一对多指针数组)。

所以我认为你的senderId和recipientIdstring列应该被称为发件人和收件人的指针types列所取代。 这样做的巨大优势是能够在消息中(或在您的条件下“倾斜”)热切地获取指向对象的查询。

做了这个改变,你是新的改进的查询看起来像这样:

 PFQuery *query = [PFQuery queryWithClassName:@"lean"]; // notice the first change for the better here: [query whereKey:@"recipient" equalTo:[PFUser currentUser]]; [query orderByDescending:@"createdAt"]; // notice the really valuable feature here: [query includeKey:@"sender"]; [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { // using the array of PFObjects understanding from your other question... for (PFObject *pfObject in objects) { NSString *messageBody = [pfObject objectForKey:@"messageBody"]; // these lines here are the punch line: PFUser *sender = [pfObject objectForKey:@"sender"]; NSString *senderName = [sender username]; NSLog(@"The message %@ was sent by %@", messageBody, senderName); } }]; 

上面要注意的重要的事情是,我们能够要求结果对象为@“发送者”列,而且,因为您已经将其更改为指针,并且因为您已经在查询上完成了一个includeKey,所以该完整对象(例如包括PFUser用户名)现在被提取。

现在简单的问题(一)。 现在,您已经从服务器获得了数据,表的数据源只不过是返回的对象。 换句话说,扔掉的senderIds数组,并将其replace为:

 @property(nonatomic, strong) NSArray *messages; 

你的查找块变得微不足道:

 [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { self.messages = objects; }]; 

numberOfRowsInSection答复messages.count ,然后从cellForRowAtIndexPath的对象中select所需的内容…

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; PFObject *message = self.messages[indexPath.row]; NSString *messageBody = [message objectForKey:@"messageBody"]; PFUser *sender = [message objectForKey:@"sender"]; NSString *senderName = [sender username]; cell.textLabel.text = senderName; return cell; } 
 function getObjects(obj, key, val) { var objects = []; for (var i in obj) { if (!obj.hasOwnProperty(i)) continue; if (typeof obj[i] == 'object') { objects = objects.concat(getObjects(obj[i], key, val)); } else if (i == key && obj[key] == val) { objects.push(obj); } } return objects; } var result = getObjects(obj, 'category_id', valu.category_id); console.log(result);