【问题标题】:NSMutableArray outputs wrong dataNSMutableArray 输出错误数据
【发布时间】:2015-12-06 21:35:52
【问题描述】:

我使用Parse.com 作为我的应用程序的后端。

每个用户都可以访问PFObjects 的列表。如果当前用户想要“收藏”一个对象,我想将其从当前用户的主列表中删除。

下面是我的代码,运行在ObjectsDidLoad

如果我注销下面的代码,PFRelation 中的 PFObject 将被删除,但在我的 UITableView 中,NSMutableArray 中的最后一项将被删除。

我在错误的位置运行它吗?

可能少了一个步骤?

谢谢!

代码如下:

- (void)objectsDidLoad:(NSError *)error {
    [super objectsDidLoad:error];

    PFRelation *relation = [[PFUser currentUser] relationForKey:@"myRelation"];
    PFQuery *relationQuery = relation.query;
    [relationQuery findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {

        NSMutableArray *arrayToShow = [NSMutableArray arrayWithArray:self.objects];

        for (PFObject *object1 in self.objects) {
            for (PFObject *object2 in results) {
                if ([[object1 objectForKey:@"title"] isEqualToString:[object2 objectForKey:@"title"]]) {
                    [arrayToShow removeObject:object1];
                }
            }
        }

        self.objectsToShowArray = [NSMutableArray arrayWithArray:arrayToShow];

        [self.tableView reloadData];
    }];
}

更多说明:

表 A 或主表加载 Parse 类中的所有对象。每个用户都可以访问它。

用户选择一个对象以转到另一个视图控制器,并且可以点击一个按钮将其添加到另一个 Parse 类。这也会创建一个 PFRelation。

因此,如果用户将对象“xyz”添加到 Parse Class B 和 Table B,我希望该对象不会为他们显示在 Table A 中(尽管它必须保留在 Parse Class A 中,因为每个用户都可以访问它) .

所以,我想查询 Parse Class A,查询 PFRelation,并从表 A 上显示的数组中删除匹配的对象。

这是我的 queryForTable 方法:

- (PFQuery *)queryForTable {
    PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
    [query orderByAscending:@"title"];

    // **********************************
    // PFRelation
    PFRelation *relation = [[PFUser currentUser] relationForKey:@"myRelation"];
    PFQuery *relationQuery = relation.query;
    [relationQuery findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {

        NSMutableArray *arrayToShow = [NSMutableArray arrayWithArray:self.objects];

        for (PFObject *object1 in self.objects) {
            for (PFObject *object2 in results) {
                if ([[object1 objectForKey:@"title"] isEqualToString:[object2 objectForKey:@"title"]]) {
                    [arrayToShow removeObject:object1];
                }
            }
        }
        self.objectsToShowArray = [NSMutableArray arrayWithArray:arrayToShow];
        [self.tableView reloadData];
    }];
    // **********************************

    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

    NSObject * object = [prefs objectForKey:@"category"];
    if(object != nil){
        //object is there
        self.categoryString = [NSString stringWithFormat:@"%@", object];

        [query whereKey:@"category" equalTo:self.categoryString];
    }

    // A pull-to-refresh should always trigger a network request.
    [query setCachePolicy:kPFCachePolicyNetworkOnly];

    // If no objects are loaded in memory, we look to the cache first to fill the table
    // and then subsequently do a query against the network.
    //
    // If there is no network connection, we will hit the cache first.
    if (self.objects.count == 0 || ![[UIApplication sharedApplication].delegate performSelector:@selector(isParseReachable)]) {
        [query setCachePolicy:kPFCachePolicyCacheThenNetwork];
    }

    return query;
}

另一次尝试:

- (PFQuery *)queryForTable {
    PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
    [query orderByAscending:@"title"];

    // **********************************
    // PFRelation Query
    PFRelation *relation = [[PFUser currentUser] relationForKey:@"myRelation"];
    PFQuery *relationQuery = relation.query;    
    [relationQuery findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {

        PFQuery *theQuery = [PFQuery queryWithClassName:self.parseClassName];
        [theQuery whereKey:@"title" matchesKey:@"title" inQuery:relationQuery];
        [theQuery findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {

            NSMutableArray *arrayToShow = [NSMutableArray arrayWithArray:self.objects];

            for (PFObject *object1 in self.objects) {
                for (PFObject *object2 in objects) {
                    if ([[object1 objectForKey:@"title"] isEqualToString:[object2 objectForKey:@"title"]]) {
                        [arrayToShow removeObject:object1];
                    }
                }
            }

            self.objectsToShowArray = [NSMutableArray arrayWithArray:arrayToShow];

            [self.tableView reloadData];
        }];

    }];
    // **********************************


    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

    NSObject * object = [prefs objectForKey:@"category"];
    if(object != nil){
        //object is there
        self.categoryString = [NSString stringWithFormat:@"%@", object];

        [query whereKey:@"category" equalTo:self.categoryString];
    }

    // A pull-to-refresh should always trigger a network request.
    [query setCachePolicy:kPFCachePolicyNetworkOnly];

    // If no objects are loaded in memory, we look to the cache first to fill the table
    // and then subsequently do a query against the network.
    //
    // If there is no network connection, we will hit the cache first.
    if (self.objectsToShowArray.count == 0 || ![[UIApplication sharedApplication].delegate performSelector:@selector(isParseReachable)]) {
        [query setCachePolicy:kPFCachePolicyCacheThenNetwork];
    }

    return query;
}

同样的结果。在日志中,它正在删除正确的PFObject,但在UITableView 中,它正在删除最后一个对象。我忽略了什么?

越来越近:

我快到了。我找到了获得所需结果的正确方法,但现在我需要在查询中添加另一层。这是我的代码:

PFRelation *relation = [[PFUser currentUser] relationForKey:@"myRelation"];
PFQuery *relationQuery = relation.query;

PFRelation *adoptedRelation = [[PFUser currentUser] relationForKey:@"mySecondRelation"];
PFQuery *adoptedRelationQuery = adoptedRelation.query;

PFQuery *matchQueryOne = [PFQuery queryWithClassName:self.parseClassName];
[matchQueryOne whereKey:@"title" matchesKey:@"title" inQuery:relationQuery];

PFQuery *matchQueryTwo = [PFQuery queryWithClassName:self.parseClassName];
[matchQueryTwo whereKey:@"title" matchesKey:@"title" inQuery:adoptedRelationQuery];

 PFQuery *queryOne = [PFQuery queryWithClassName:self.parseClassName];
 [queryOne whereKey:@"title" doesNotMatchKey:@"title" inQuery:matchQueryOne];
 [queryOne whereKey:@"title" doesNotMatchKey:@"title" inQuery:matchQueryTwo];
 [queryOne orderByAscending:@"title"];

我需要运行两个关系并将结果组合起来,然后得到输出。

在这个例子中,只有我的 queryOne 中的第二种情况被命中。

【问题讨论】:

  • 这是一个 pftableviewcontroller 吗?
  • 是的,它是一个 PFQueryTableViewController 子类
  • 为什么要比较标题?您可以省略外部循环,并在第二个循环中简单地说 [arrayToShow removeObject:object2](这将是您唯一的循环)
  • 保罗:没用。不删除任何东西。将结果数组中匹配 PFObject 的标题与 self.objects 中匹配的 PFObject 进行比较,然后如果匹配,则需要将其从 NSMutableArray 中删除。

标签: ios objective-c uitableview parse-platform nsmutablearray


【解决方案1】:

PFQueryTableViewController 维护其要从您提供的查询中显示的项目列表。如果不取消 PFQueryTableViewController 为您提供的大部分逻辑,您就无法进行不同的查询并过滤这些结果。

更新您提供的查询 yo PFQueryTableViewController 以包含限制返回项目的子句,因此您无需在本地进行过滤。

【讨论】:

  • 仍然看到数组中的最后一项被删除,而不是关系中的项
  • 你需要解释更多关于你在做什么,你如何编辑表格内容,你向服务器发送什么请求
  • 我只想查询 Parse Class A,PFRelation,找到匹配的 PFObject,然后从主屏幕上的表格中显示的数组中删除它们。上面添加了更多细节,使用我的 queryForTable 代码
  • 您最近的尝试是正确的方法。以前从未尝试使用所有相同的键添加 2 个子查询。请记住,查询(包括子查询)默认为 100 个项目,最多为 1000 个项目,这可能会影响您的结果...
  • 是的,我认为最简单的方法是将所有“标记”项目放入一个类和一个关系中。现在一个用户有 2 个选项(所以 2 个类)。目前他们总共只能通过 40 项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
相关资源
最近更新 更多