所以,我遇到了一个奇怪的问题。我正在使用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..........
}
答案 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];
}