masonry+懒加载=我的2天时间

这两天我有点炸。。炸的很彻底!在布局上我这两年一直是代码布局,自适应啥的就不说了。一直比较喜欢masonry这个玩意儿-。-没换过!
前两天我在重构一个比较老(low)的项目的时候(ps:我就不吐槽这个项目一个vc可以写上2000多行我看着想吐的代码的了),对一个个人页面进行重写操作。抽离出了4个可复用的视图模型。常规布局云云。。。代码布局给我的感觉很爽,思路很正,也很流畅。想想这每一个约束的添加,屏幕适配,一气呵成。写完了一运行,尼玛炸了!
报错地方是在masonry内部,第一反应就是约束加错了。赶紧回去看了看每一个视图,每一个控件约束是不是有错误,检查完后,,没有。这就尴尬了。
好吧,,还是看看到底啥错误吧,,couldn't find a common superview。。。啥情况,,没有把约束加在同一个父视图上?不能够吧!我又看了一遍,,么有啊!写的都很正常。。接下来就是我进入了无休止的调试,修改,运行,一直到内心崩溃。
嗯,炸了!默默的吸了一口烟,重新来!!!
第一:我把视图继承的基类中的方法注释了。。手写(心态微炸,各种本方法);
第二:把视图中所有的控件啊,初始化呀,约束呀等等,全都写在一个方法里面(当然就是一个视图模型内的整合在一个方法里面了),然后运行。嗯哼?成功了,,显示出来了。。。ok,心里面踏实多了;
第三:把基类方法重新写回去,然后把视图类重新继承基类并实现方法,,嗯哼?成功了。ok
第四:把视图类中关于控件的约束重新分离出来,我是这么构建的(光说也没啥意思)

- (void)Base_setupViews
{
    //这里面是初始化控件方法,然后添加到视图
    //_label = [...]...就不展示了。。。
    [self setNeedsUpdateConstraints];
    [self updateConstraintsIfNeeded];
}
- (void)updateConstraints
{
   //设置的约束
   SF(weakSelf)
   [self.label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(weakSelf.contentView.mas_left).mas_offset(8);
        make.centerY.mas_equalTo(weakSelf.contentView.mas_centerY);
        make.size.mas_equalTo(CGSizeMake(25, 25));
    }];
    [super updateConstraints]; 
}

运行。。嗯哼?ok。。
第五:接着把Base_setupViews中的代码进行分类,,(因为我一直是这个思想(13年初学ios的时候就是苹果公司的一位大大教我的)有什么东西?这个东西要干啥?这个东西怎么干的?就这三步。)把每一个控件懒加载一下(就是重写一下控件的getter方法),嗯,抽离完了,基本上这个.m又恢复到了最初的模样,感觉要炸。一运行,嗯炸了。
第六:反思了一下,之前步骤都没有问题,就是在懒加载这出事故了。。但是想想懒加载这东西用了这么长时间也应该没啥,最后我就把重点放到了三步走的第二步(将控件放到视图上)

[self.contentView addSubview: _label];

找到了,就是这么个玩意让我炸了!
炸的原因:懒加载是重写getter方法,_label只是访问一个局部变量,仅仅是获取自己的实例变量,并不包含set和get的方法。而masonry中是使用的self.label,这个玩意实际上是用了get和set方法间接调用,可以这么理解self.label ====>>>>[self label];
如果用一个栗子来说一下这种病态的写法,我可以这么说:你给我针,你给我线,你让我去干活,我去了,,但是怎么干没说,索性就不干了。
第七:修改将控件加载方法

[self.contentView addSubview: self.label];

ok。。。
总结一小下:
视图模型的三个步骤

//懒加载(延迟加载)
- (UILabel *)label
{
    if (!_label) {
        _label = [[UILabel alloc] init];
    }
    return _label;
}
//添加控件到视图模型
- (void)Base_setupViews
{
    [self.contentView addSubview:self.label];
    [self setNeedsUpdateConstraints];
    [self updateConstraintsIfNeeded];
}
//设置更新一下约束
- (void)updateConstraints
{
    SF(weakSelf)
    [self.label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(weakSelf.contentView.mas_left).mas_offset(8);
        make.centerY.mas_equalTo(weakSelf.contentView.mas_centerY);
        make.size.mas_equalTo(CGSizeMake(25, 25));
    }];
    [super updateConstraints]; 
}

self.时是调用一个getter方法。会使引用计数加一,而(下划线)不会使用引用计数器加一。使用self.是更好的选择,不仅可以使用懒加载,同时也避免了使用下滑线的时候忽略了self这个指针,容易在BLock中造成循环引用。同时,使用 _是获取不到父类的属性,因为它只是对局部变量的访问。
ps:我觉得我这解决问题的思路也是可以的(真的心态炸了的笨方法。。哈哈)
不喜勿喷吧!
有啥更好的解释或者思路的分享一下,感谢各位大大!

你可能感兴趣的:(masonry+懒加载=我的2天时间)