You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UITableView滑动或触摸时无法刷新数据或给cell赋值如何解决?

问题根因

当UITableView处于滑动/触摸交互状态时,主线程RunLoop会切换到NSEventTrackingRunLoopMode(iOS系统为了保证滑动流畅性设计的专属模式),该模式下默认只会处理和触摸交互相关的任务:

  • 如果你的Socket监听任务是注册在NSDefaultRunLoopMode下,滑动时Socket的回调会被暂时挂起,你不会收到新数据,自然不会触发刷新
  • 即使你收到了数据,如果刷新UI的任务只注册在默认RunLoop模式下,同样会被阻塞不执行
解决方案
  • 第一步:确保所有UI操作严格在主队列执行,错误的队列调度会导致刷新不生效,正确写法如下
    Objective-C版本:
    // 收到Socket数据先更新数据源数组,再刷新UI
    self.dataArray = newDataFromSocket;
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });
    
    Swift版本:
    // 先更新数据源
    self.dataArray = newDataFromSocket
    DispatchQueue.main.async {
        self.tableView.reloadData()
    }
    
  • 第二步:将Socket的运行模式设置为通用模式,保证滑动时也能正常收到数据回调,以常用的CocoaAsyncSocket库为例:
    // 初始化Socket后设置运行模式
    self.socket.runLoopModes = [NSRunLoopCommonModes];
    
  • 第三步:如果上述操作仍未生效,可以将刷新任务显式指定到通用RunLoop模式下执行:
    [self performSelector:@selector(reloadTableView) 
                 onThread:[NSThread mainThread] 
               withObject:nil 
            waitUntilDone:NO 
                    modes:@[NSRunLoopCommonModes]];
    
    - (void)reloadTableView {
        [self.tableView reloadData];
    }
    
  • 可选优化:如果数据更新频率高于1次/秒,建议增加防抖逻辑:收到新数据后先更新数据源、标记需要刷新的状态,每1-2秒统一调用一次reloadData,避免频繁刷新导致滑动卡顿。

内容的提问来源于stack exchange,提问作者Nawin Poolsawad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 05:51:03