iOS 懒加载View可能出现的坑

⚠️ 可能会出现的BUG: View的懒加载执行了两次alloc

最近写代码时候遇到了懒加载执行两次的问题。代码如下


@interface ViewController : UIViewController
@property (nonatomic, strong) UITableView *tableView;
@end


- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.tableView];
    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(0);
    }];
}

/// 懒加载
- (UITableView *)tableView{
    if (!_tableView) {
        // self.view 可能会导致此处创建两次
        _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
//        应改为⬇️
//       _tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain];
        _tableView.contentInset = UIEdgeInsetsMake(70, 0, 0, 0);
    }
    return _tableView;
}

正常的情况下,上面的代码不会出现任何问题。代码执行的顺序 viewDidLoad -> self.tableView -> self.tableView懒加载创建 ->addSubview: 最后展示在view上面

这里会涉及一个概念: viewDidLoad什么时候调用
个人浅层理解:viewDidLoad 就是 vc.view的懒加载。只会执行一次
这里有更详细的图文讲解

出现问题的场景:在[[vc alloc] init]之后 -> 外部调用并使用了vc.tableView ->[push:vc]之前
这个时候上面的代码就会出现tableView的懒加载alloc两次的问题

问题原因: 代码顺序
  1. [[vc alloc] init] vc初始化
  2. 外部调用了vc.tableView 执行tableView的懒加载。
  3. 这时_tableView == nil执行了创建方法
  4. 因为tableView创建的时候使用了self.view.bounds从而触发了viewDidLoad方法
  5. viewDidLoad 内部引用了self.tableView执行懒加载(get方法)
  6. 这时_tableView == nil仍然为空。再次执行创建方法
  7. 最终导致了alloc两次。
解决方法

self.view.bounds替换为[UIScreen mainScreen].bounds

疑问

为什么创建的时候Frame不采用CGRectZero。毕竟后面也用了Masonry

原因

为了解决:UITableView 设置 contentInset 没有自动改变

你可能感兴趣的:(iOS 懒加载View可能出现的坑)