Parse PFQueryTableViewController objectsDidLoad在numberOfRowsInSection之前没有执行

时间:2014-07-05 08:51:51

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

所以,我遇到了一个奇怪的问题。我正在使用Parse的iOS API,并使用PFQueryTableViewController向用户显示项目。这些项目分为两部分。应用程序首次启动时,它会在运行objectsDidLoad方法之前运行numberOfRowsInSection方法。这很完美,因为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..........
    }

2 个答案:

答案 0 :(得分:3)

我通过多线程处理我的应用来解决这个问题。我使用了名为BOOL的全局isDoneLoading来检查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方法之前执行。

答案 1 :(得分:0)

objectsDidLoad方法

的末尾添加此内容
if(self.tableView.numberOfSections != self.sections.allKeys.count)
    {
        [self.tableView reloadData];
    }