iOS bug 收录

tableview reloadData 坑

2019-04-28  本文已影响0人  iOS_Ru

以下简单的代码 偶尔会造成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
上一篇下一篇

猜你喜欢

热点阅读