2

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

似乎每次预取重新加载表视图时,表视图都会要求更多预取,在调用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(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) 方法调用 tableView.reloadData() 或 tableView.reloadRows(...) !这些方法引发 UITableView 调用 prefetchRowsAt... 从而导致无限循环。

Soo.. Apple 打算如何将预取用于 Diffable 数据源?... -.-

4

0 回答 0