iOS table view diffable 数据源和预取

问题描述

使用 NSDiffableDataSourceSnapshot- (void)tableView:(nonnull UITableView *)tableView prefetchRowsAtIndexPaths:(nonnull NSArray<NSIndexPath *> *)indexPaths 的正确方法是什么。

好像每次prefetch重新加载table view的时候,table view都会要求更多的prefetching,调用apply快照后,造成无限循环。

- (void)reloadViews {
    //[self.tableView reloadData];
    
    NSMutableArray *items = [NSMutableArray new];
    for (TCHChannel* channel in self.channels) {
        [items addobject:channel.sid];
    }
    if ([items count] == 0) {
        return;
    }
    
    NSDiffableDataSourceSnapshot<ConversationSectionType*,Nsstring*> *snapshot =
    [[NSDiffableDataSourceSnapshot<ConversationSectionType*,Nsstring*> alloc] init];
    ConversationSectionType *main = [ConversationSectionType new];
    main.section = kMain;
    [snapshot appendSectionsWithIdentifiers:@[main]];
    [snapshot appendItemsWithIdentifiers:items intoSectionWithIdentifier:main];
    [self.diffDataSource applySnapshot:snapshot animatingDifferences:NO];
}

这里是预取方法

- (void)tableView:(nonnull UITableView *)tableView prefetchRowsAtIndexPaths:(nonnull NSArray<NSIndexPath *> *)indexPaths {
    for (NSIndexPath *indexPath in indexPaths) {
        TCHChannel *channel = [self channelForIndexPath:indexPath];
        
        NSMutableSet *currentChannelIds = [NSMutableSet new];
        for (ConversationListviewmodelUpdateOperation *op in self.modelQueue.operations) {
            [currentChannelIds addobject:[op channelId]];
        }
        if ([currentChannelIds containsObject:channel.sid]) {
            continue;
        }
        
        NSParameterassert(channel != nil);
        ConversationListviewmodelUpdateOperation *op = [[ConversationListviewmodelUpdateOperation alloc] initWithChannel:channel cache:self.channelviewmodelsCache];
        op.completionBlock = ^{
            dispatch_async(dispatch_get_main_queue(),^(void){
                [self reloadViews];
            });
        };
        [self.modelQueue addOperation:op];
    }
}

模型队列只是操作队列:

- (NSOperationQueue*)modelQueue {
    if (_modelQueue == nil) {
        _modelQueue = [[NSOperationQueue alloc] init];
        _modelQueue.maxConcurrentOperationCount = 4;
    }
    return _modelQueue;
}

有没有一种方法可以在不apply 要求更多索引的情况下对可区分的数据源使用预取?

编辑:

因此在预取方法调用 reloadData 会导致无限循环.. 根据 https://andreygordeev.com/2017/02/20/uitableview-prefetching/

警告:不要调用 tableView.reloadData() 或 tableView.reloadRows(...) from tableView(_ tableView: UITableView,prefetchRowsAt indexPaths: [IndexPath]) 方法!这些方法引起 UITableView 调用 prefetchRowsAt... 从而导致无限循环。

Soo.. Apple 打算如何将预取与 Diffable Data Sources 一起使用? ... -.-

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)