如何通过键和值获取对象 [英] how to get object by key and value

查看:75
本文介绍了如何通过键和值获取对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an object called masterMessages filled with objects called messages. Each message object has five keys:


  • objectId

  • senderId

  • senderName

  • messageBody

  • 时间戳

  • objectId
  • senderId
  • senderName
  • messageBody
  • timestamp

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

Basically what I am doing now is querying all the messages sent to my user in this object called masterMessages. Then i'm using:

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

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

to get all the different sender ids (senderId) in an array called senderIds. With this I will populate my conversations table. But i want to populate it with the sender names (senderName) and not the senderIds. I only do it this way in case two users have the same name.

我正在寻找:


  1. 怎么说 get valueForKey :@@ senderName为此senderId


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

这是我的代码:

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

note: im using 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;
   }
}


推荐答案

有问题中有几个问题,一个是如何取消对PFObject的引用,我们已经处理了在另一个线程上。这个问题的其余部分是关于(a)如何使用解析对象来构建数据源以支持表格视图,以及更难的一个(b)如何从相关对象中获取信息。

There are a few issues in the question, one is how to dereference PFObjects, which we took care of on another thread. The rest of this question is about (a) how to use parse objects to build a datasource to support a tableview, and a harder one (b) how to get information from related objects.

从(b)开始,难度更大:有几种关联对象的方法。您选择的是包含相关对象ID的字符串型列,这很直观(特别是如果您具有SQL背景),但建议最少。建模一对一或小型一对多关系的更好(最佳)方法是使用指针(如果是一对多则为指针数组)。

Starting with (b), the harder one: There are a few ways to relate objects. Your choice a string-typed column containing the related object id, is intuitive (especially if you have an SQL background), but the least advisable. The better (best) way to model a one-to-one or small one-to-many relation is with a pointer (or array of pointers if one-to-many).

因此,我认为您的senderId和receiverId字符串列应替换为称为sender和收件人的指针类型的列。这样做的巨大优势是可以在消息查询(或用您的术语表示精简)中急切地获取那些指向对象的功能。

So I think your senderId and recipientId string columns should be replaced by pointer-typed columns called sender and recipient. The huge advantage of this is the ability to eagerly fetch those pointed-to objects on the message (or "lean" in your terms) query.

已经进行了更改,您是经过改进的新查询,如下所示:

Having made that change, you're new improved query looks like this:

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);
    }
}];

上面要注意的重要一点是我们能够向@ sender询问生成的对象列,并且由于已将其更改为指针,并且由于已对查询执行了includeKey,因此现在已获取了完整的对象(例如,包括PFUser用户名)。

The important thing to notice above is that we were able to ask resulting objects for the @"sender" column, and, because you've changed it to a pointer, and because you've done an includeKey on the query, that complete object (e.g. including the PFUser username) is now fetched.

现在是简单的问题(a)。现在您已经拥有了来自服务器的数据权,该表的数据源只不过是返回的对象。换句话说,丢弃 senderIds 数组并将其替换为:

Now the easy question (a). Now that you have the data right from the server, the datasource for the table is nothing more than the returned objects. In other words, throw away the the senderIds array and replace it with:

@property(nonatomic, strong) NSArray *messages;

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

Your find block becomes trivial:

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

为<$ c回答 messages.count $ c> numberOfRowsInSection ,然后从 cellForRowAtIndexPath ...

Answer messages.count for numberOfRowsInSection, and then pick what you need from the objects in cellForRowAtIndexPath...

- (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;
}

这篇关于如何通过键和值获取对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆