ios - 确保 UITableView 以原子方式重新加载的最佳方法是什么?

标签 ios uitableview atomic

我有一个 UITableView,它的数据源在很短的时间内随机更新。随着更多对象被发现,它们被添加到 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) block ,但我想尽可能避免这样做,因为它很昂贵。

最佳答案

我推荐的方法是创建一个私有(private)队列,用于将批量更新同步发布到主队列(其中 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];
        });
    });
}

通过这种方式,您不会阻塞任何其他线程,并且基于 block 的方法可确保 TableView 的动画 block (抛出异常的 block )以正确的顺序执行。 Rapid row insertion into UITableView causes NSInternalInconsistencyException中有更详细的解释.

关于ios - 确保 UITableView 以原子方式重新加载的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18108095/

相关文章:

java - 如何安全地更新一个有很多读者和一个作者的文件?

iOS:如何为应用程序的所有 ImageView 设置 'accessibilityIgnoresInvertColors' 为真?

button - iOS自定义按钮类似于barbutton

objective-c - objective-c 中的计算没有返回正确的值

ios - 删除后重用的UITableViewCell格式

ios - iOS 上的 Metal 原子操作性能

c++ - Cuda 原子和条件分支

c# - 检测 AVPlayerItem 状态变化

ios - 选择和取消选择 UITableViewCells - Swift

objective-c - 根据内容在 UITableViewCell 中调整 UIWebView 的大小