5

我有一个 UITableView,它的 dataSource 在很短的时间内随机更新。随着越来越多的对象被发现,它们被添加到 tableView 的数据源中,我插入了特定的 indexPath:

[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];

数据源位于管理器类中,并在更改时发布通知。

- (void)addObjectToDataSource:(NSObject*)object {
    [self.dataSource addObject:object];
    [[NSNotificationCenter defaultCenter] postNotification:@"dataSourceUpdate" object:nil];
}

viewController 收到此通知时会更新 tableView。

- (void)handleDataSourceUpdate:(NSNotification*)notification {
    NSObject *object = notification.userInfo[@"object"];
    NSIndexPath *indexPath = [self indexPathForObject:object];

    [self.tableView beginUpdates];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.tableView endUpdates];
}

这很好用,但我注意到在某些情况下,当第一个对象调用 endUpdates 时,会发现第二个对象,并且我收到一个异常,声称我的数据源中有两个对象,而 tableView 需要一个对象。

我想知道是否有人想出了一种更好的方法来将行自动插入到 tableView 中。我正在考虑在更新周围放置一个@synchronized(self.tableView)块,但如果可能的话,我想避免这种情况,因为它很昂贵。

4

1 回答 1

4

我推荐的方法是创建一个私有队列,用于将批量更新同步发布到主队列(其中addRow是将项目插入到给定 indexPath 的数据模型中的方法):

@interface MyModelClass ()
@property (strong, nonatomic) dispatch_queue_t myDispatchQueue;
@end

@implementation MyModelClass

- (dispatch_queue_t)myDispatchQueue
{
    if (_myDispatchQueue == nil) {
        _myDispatchQueue = dispatch_queue_create("myDispatchQueue", NULL);
    }
    return _myDispatchQueue;
}

- (void)addRow:(NSString *)data atIndexPath:(NSIndexPath *)indexPath
{
    dispatch_async(self.myDispatchQueue, ^{
        dispatch_sync(dispatch_get_main_queue(), ^{
            //update the data model here
            [self.tableView beginUpdates];
            [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            [self.tableView endUpdates];
        });
    });
}

通过这样做,您不会阻塞任何其他线程,并且基于块的方法可确保表格视图的动画块(引发异常的动画块)以正确的顺序执行。在快速行插入 UITableView 导致 NSInternalInconsistencyException中有更详细的解释。

于 2013-08-07T18:28:27.397 回答