我有一个自定义的TableViewCell,我从异步函数中的数据库获取数据,该异步函数返回一个UserObject,其中包含我需要的数据。我的问题是cellForRowAtIndexPath
在异步块完成之前返回了单元格。我该如何解决这个问题?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"ImageWorkoutCellCollapsed";
ImageWorkoutCellCollapsed *cell = (ImageWorkoutCellCollapsed *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if(cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ImageWorkoutCellCollapsed" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
WorkoutObject *workout = [[WorkoutObject alloc]init];
workout = [appDelegate.workoutObjectsArray objectAtIndex:indexPath.row];
cell.workoutTitle.text = workout.workoutTitle;
cell.workoutViewCount.text = workout.workoutDescription;
__block UserObject *cellUserObject = [[UserObject alloc]init];
[dbPointer getUserObjectFromDB:workout.workoutOwnerID completion:^(UserObject *result)
{
cellUserObject = result;
}];
cell.userName.text = cellUserObject.username;
return cell;
}
答案 0 :(得分:0)
在数据可用之前,您应确保未调用cellForRowAtIndexPath。 您有一个行数,您必须将此计数设置为N,但您还没有提取N个数据项。 在获取所有数据之前,请不要设置此数字。
OR
当数据到达时,不断更新数量或行并刷新表格视图。
OR
使用占位符数据返回单元格。然后,一旦单元格的实际数据可用,就更新内容并刷新表格。
OR
以上所有解决方案都涉及将数据提取移出cellForRowAtIndexPath。但是 IFF 对获取数据的调用很快,因此不会减慢表的绘制速度,您需要将fetch从异步转换为同步。但是视图控制器组件直接访问数据库并不是一个好设计,而应该转到模型,模型应该抽象出数据在数据库中的实现细节。
答案 1 :(得分:0)
您应该将单元格更新转换为行的重新加载,如下所示:
1)你应该使用dequeueReusableCellWithIdentifier:forIndexPath而不是你正在使用的版本。
2)你不应该检查(cell == nil)为1)永远不应该返回nil。
3)通过workoutOwnerID添加新的NSMutableDictionary属性来缓存UserObject
。
4)当您被要求提供单元格时,请从3)中查找字典以查看它是否包含您的数据对象。如果没有,则运行数据库查询。如果它有对象,请设置单元格值。
5)在DB查找的完成处理程序中,通过workoutOwnerID将返回的对象缓存到新字典中。然后只需请求表重新加载该行。
结果是当更新它们所代表的数据时更新单元格。