2

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

2 回答 2

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

于 2014-07-07T02:30:34.950 回答
0

objectsDidLoad方法的末尾添加这个

if(self.tableView.numberOfSections != self.sections.allKeys.count)
    {
        [self.tableView reloadData];
    }
于 2016-05-04T14:20:28.470 回答