objc懒加载的坑

我们定义一个objc的属性时,有时候会用懒加载,比如

- (UITableView *)tableView {
    if (!_tableView) {
        _tableView = [UITableView new];  
        _tableView.delegate = self;
    }
    return _tableView
}

一般情况下是没什么问题,但是如果在dealloc方法里调用self.tableView,如下:

- (void)dealloc {
    [self.tableView];
}

如果这时_tableView为nil,则会创建tableView,调用_tableView.delegate = self,因为UITableView的delegate属性为weak(一般我们为了避免循环引用,会把delegate这种属性设置成weak),也就是说为self添加了一个weak指针。

@property (nonatomic, weak) id<UITableViewDelegate> delegate;

那么问题来了,objc的runtime为对象添加weak指针时,会检测对象是否正在dealloc,如果正在dealloc,就会进入_objc_fatal函数,然后崩溃。以下是崩溃时的call stack

0	__terminate_with_payload ()
1	abort_with_payload_wrapper_internal ()
2	abort_with_reason ()
3	_objc_fatalv(unsigned long long, unsigned long long, char const*, char*) ()
4	_objc_fatal(char const*, ...) ()
5	weak_register_no_lock ()
6	objc_storeWeak ()

解决方案有几种:
1.在dealloc方法中,使用_tableView代替self.tableView。
2.把self.tableView移出dealloc方法。
3.不在懒加载里面设置weak指针
4.不使用懒加载。

posted @ 2023-08-29 15:37  wkdwangjun  阅读(55)  评论(0编辑  收藏  举报