美文网首页iOS bug 收录
tableview reloadData 坑

tableview reloadData 坑

作者: iOS_Ru | 来源:发表于2019-04-28 11:54 被阅读0次

    以下简单的代码 偶尔会造成crash

        [self.tableView reloadData];
        [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:(UITableViewScrollPositionBottom) animated:YES];
    

    报错的Crash


    image.png

    这· 个是因为reloadData的 刷新机制, 现在看下它的刷新步骤

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
        self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
        
        self.tableView.dataSource = self;
        self.tableView.delegate = self;
        [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
        [self.view addSubview:self.tableView];
        
        
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        NSLog(@"numberOfRow");
        return 1;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        
        NSLog(@"heightForRow");
        return 44;
    }
    
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        NSLog(@"cellForRow");
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
        
        cell.textLabel.text = @"dd";
        cell.backgroundColor = [UIColor redColor];
        return cell;
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        
        NSLog(@"begin");
        [self.tableView reloadData];
        NSLog(@"end");
    }
    

    运行后的打印顺序


    image.png

    就可以看到 如果你在 reloadData只有写 对cell的一些处理 比如滚动 或者删除 就可能引起越界 等一些奇怪的Crash

    解决办法

    第一种解决办法
      NSLog(@"begin");
        [self.tableView reloadData];
        dispatch_async(dispatch_get_main_queue(), ^{
            //写相关处理Cell的方法 比如 scrollToRowAtIndexPath 等
            NSLog(@"end");
        });
    
    第二种解决办法
      NSLog(@"begin");
        [self.tableView reloadData];
        [self.tableView layoutIfNeeded];
        //写相关处理Cell的方法 比如 scrollToRowAtIndexPath 等
        NSLog(@"end");
    
    
    第三种写法
       NSLog(@"begin");
        [self.tableView reloadData];
        [CATransaction begin];    
        [CATransaction setCompletionBlock:^{
            //写相关处理Cell的方法 比如 scrollToRowAtIndexPath 等
            NSLog(@"end");
        
        }];
        [CATransaction  commit];
    

    这三种执行方法的控制台打印都是

    2019-04-28 11:46:13.183054+0800 testUU[26623:383414] begin
    2019-04-28 11:46:13.183602+0800 testUU[26623:383414] numberOfRow
    2019-04-28 11:46:13.183948+0800 testUU[26623:383414] cellForRow
    2019-04-28 11:46:13.184394+0800 testUU[26623:383414] heightForRow
    2019-04-28 11:46:13.184765+0800 testUU[26623:383414] heightForRow
    2019-04-28 11:46:13.184976+0800 testUU[26623:383414] heightForRow
    2019-04-28 11:46:13.185202+0800 testUU[26623:383414] heightForRow
    2019-04-28 11:46:13.185469+0800 testUU[26623:383414] end
    

    相关文章

      网友评论

        本文标题:tableview reloadData 坑

        本文链接:https://www.haomeiwen.com/subject/pmtdnqtx.html