【问题标题】:Parse PFQueryTableViewController objectsDidLoad not executing before numberOfRowsInSection解析 PFQueryTableViewController objectsDidLoad 在 numberOfRowsInSection 之前未执行
【发布时间】:2014-07-05 08:51:50
【问题描述】:

所以,我遇到了一个奇怪的问题。我正在使用 Parse 的 iOS API,并使用 PFQueryTableViewController 向用户显示项目。这些项目分为两个部分。当应用程序第一次启动时,它会在运行numberOfRowsInSection 方法之前运行objectsDidLoad 方法。这是完美的,因为objectsDidLoad 方法能够定义表格视图的每个部分中存在的对象数量。我还启用了 tableView 的“下拉刷新”功能,该功能运行良好。因此,如果我在解析数据浏览器上更改某个数据值,这应该会导致向用户显示的项目之一更改部分。如果我在更改该数据值后重新启动应用程序,则该对象将出现在其他部分中,就像它应该出现的那样。然而,问题是,如果我在解析时更改数据值以导致对象更改部分,然后拉下 tableView 以刷新数据,应用程序崩溃,我想我知道为什么。虽然objectsDidLoad 方法在应用程序第一次运行时在numberOfRowsInSection 方法之前执行,但当我拉下tableView 并刷新数据时,它实际上在numberOfRowsInSection 之后执行。这会导致cellForRowAtIndexPath 方法尝试访问存储每个部分中的对象的数组中不存在的数组索引。

我的问题:在调用numberOfRowsInSection 方法之前,如何刷新对象并更新存储每个部分的对象的数组?

这是我的objectsDidLoad 方法:

    - (void)objectsDidLoad:(NSError *)error {
       //dataArray, firstSectionArray, and secondSectionArray are global NSMutableArrays
       [super objectsDidLoad:error];

       firstSectionArray = [[NSMutableArray alloc]init];
       secondSectionArray = [[NSMutableArray alloc]init];
       NSMutableDictionary *firstSectionDictionary = [[NSMutableDictionary alloc]init];
       NSMutableDictionary *secondSectionDictionary = [[NSMutableDictionary alloc]init];
       dataArray = [[NSMutableArray alloc]init];

       for (int i = 0; i < [self.objects count]; i++) {
           if ([[[self.objects objectAtIndex:i]objectForKey@"Level"]intValue] == 1) {
               [firstSectionArray addObject:[self.objects objectAtIndex:i]];
           }
           else {
               [secondSectionArray addObject:[self.objects objectAtIndex:i]];
           }
       }

       firstSectionDictionary = [NSMutableDictionary dictionaryWithObject:firstSectionArray forKey:@"data"];
       secondSectionDictionary = [NSMutableDictionary dictionaryWithObject:secondSectionArray forKey:@"data"];
       [dataArray addObject:firstSectionDictionary];
       [dataArray addObject:secondSectionDictionary];
    }

这是我的numberOfRowsInSection 方法:

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        NSDictionary *dictionary = [dataArray objectAtIndex:section];
        NSMutableArray *array = [dictionary objectForKey:@"data"];
        return [array count];
    }

这是我的cellForRowAtIndexPath 方法:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
        static NSString *CellIdentifier = @"Cell";

        PFTableViewCell *cell = (PFTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[PFTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        }

        NSMutableDictionary *dictionary = [dataArray objectAtIndex:indexPath.section];
        //This next line is where it's crashing
        PFObject *newObject = [[dictionary objectForKey:@"data"]objectAtIndex:indexPath.row];

        //More irrelevant code below..........
    }

【问题讨论】:

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


    【解决方案1】:

    我已通过对我的应用程序进行多线程处理来解决此问题。我使用了一个名为isDoneLoading 的全局BOOL 来检查objectsDidLoad 方法是否已完成执行。这是我的objectsDidLoad 方法:

    - (void)objectsDidLoad:(NSError *)error {
         [super objectsDidLoad:error];
    
         dataArray = [[NSMutableArray alloc]init];
    
         NSMutableArray *firstSectionArray = [[NSMutableArray alloc]init];
    
         NSMutableArray *secondSectionArray = [[NSMutableArray alloc]init];
    
         for (int i = 0; i < [self.objects count]; i++) {
             //First Section
             if ([[[self.objects objectAtIndex:i]objectForKey:@"Level"]intValue] == 1) {
                 [firstSectionArray addObject:[self.objects objectAtIndex:i]];
             }
             //Second Section
             else  {
                 [secondSectionArray addObject:[self.objects objectAtIndex:i]];
                 /*} else {
                  //Other Sections
                  [secondSectionArray addObject:[self.objects objectAtIndex:i]];
                  }*/
             }
         }
    
         NSMutableDictionary *firstSectionDictionary = [NSMutableDictionary dictionaryWithObject:firstSectionArray forKey:@"data"];
         [dataArray addObject:firstSectionDictionary];
    
          NSMutableDictionary *secondSectionDictionary = [NSMutableDictionary dictionaryWithObject:secondSectionArray forKey:@"data"];
         [dataArray addObject:secondSectionDictionary];
    
         isDoneLoading = true;
     }
    

    这是我的numberOfRowsInSection 方法:

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        dispatch_group_t d_group = dispatch_group_create();
        dispatch_queue_t bg_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
        __block NSDictionary *dictionary;
        __block NSMutableArray *array;
    
        dispatch_group_async(d_group, bg_queue, ^{
           // [self queryForTable];
            [self objectsDidLoad:NULL];
            while (!isDoneLoading) {}
    
            dictionary = [dataArray objectAtIndex:section];
            array = [dictionary objectForKey:@"data"];
        });
    
        dispatch_group_wait(d_group, DISPATCH_TIME_FOREVER);
    
        isDoneLoading = false;
        return [array count];
    }
    

    使用这种多线程方法,我能够始终阻止numberOfRowsInSection 方法在objectsDidLoad 方法之前执行。

    【讨论】:

    • 涂料。一个非常需要的东西。我遇到了完全相同的问题。
    【解决方案2】:

    objectsDidLoad 方法的末尾添加这个

    if(self.tableView.numberOfSections != self.sections.allKeys.count)
        {
            [self.tableView reloadData];
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-01
      • 2018-02-15
      • 2015-10-08
      • 2010-10-24
      • 2012-12-28
      • 1970-01-01
      相关资源
      最近更新 更多