Masonry和UITableView-FDTemplateLayoutCell结合使用时遇过的坑

前言

    纯代码自动布局,首选框架当然是Masonry,这是一个很赞的框架。

    UITableView-FDTemplateLayoutCell也是一个很高端且很实用的框架。

    那么,很多时候我们在同一个项目中需要同时使用着两个框架。其实这两个框架同时使用并没有什么特殊技巧,使用起来也很简单。不会用的童鞋可以参考如下博客:

http://www.cnblogs.com/geshihuayoutiao/p/4671246.html

    本文要说的呢,是这两个框架一起使用的时候,在某种特定情况下产生的问题,以及问题解决的方法。


情景再现

    一个聊天界面,用的tableView,cell高度计算使用UITableView-FDTemplateLayoutCell,tableView的数据源方法中向cell传递数据是通过setMessageModel:方法传递。这个时候,tableView获取cell高度的代理方法实现就是下面的样子:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    DPNMessageModel *messageModel = [_dataArray objectAtIndex:indexPath.row];
    NSString *identifier = [DPNChatRoomCellBase cellIdentifierForMessageConfiguration:messageModel];
    //计算高度并返回
    return [tableView fd_heightForCellWithIdentifier:identifier cacheByIndexPath:indexPath configuration:^(DPNChatRoomCellBase *cell) {
	    [cell setMessageModel:messageModel];//重点在这!!!
    }];
}

    从代码中看出,计算cell高度的方法是UITableView-FDTemplateLayoutCell提供的方法,这个方法的block回调调用setMessageModel:方法。

    从断点实验中得出,计算一个cell的高度,这个block会回调两次,也就是说setMessageModel:要执行两次。

    这好像没啥问题,两次也不多,加上数据源方法,配置一个cell,setMessageModel:方法总共执行三次。一般情况下,setMessageModel:方法肯定很简单,无非就是传递一些属性值。

    但是,但是,问题就来了!

    如果cell较为复杂,而且cell的约束需要根据setMessageModel:传来的值进行调整(这是问题重点)。这种情况下,就需要在setMessageModel:方法中主动调用设置约束的方法,不管你是重写updateConstrains还是自己写的设置约束方法,总之就是在执行setMessageModel:方法的时候设置约束的方法得再执行一次。这样的话,每配置一个cell,花的时间就有点长了,页面就显得不那么流畅了,压力测试的时候界面就很卡。


问题解决

    计算cell高度的时候,调用两侧setMessageModel:方法,这个没办法。所以配置一个cell需要调用三次setMessageModel:也是没办法的。那么,就必须从setMessageModel:内部入手。

  • 一是要精简setMessageModel:方法内部的效率。这个没啥说的。
  • 二是要减少自动约束设置方法执行次数,设置约束还是挺耗时的,所以这个是优化重点。

    刚才说了,由于约束要根据setMessageModel:传进来的属性值做调整,所以在setMessageModel:方法中得主动调用约束设置方法。比如说聊天界面,群聊的时候,别人发来的消息,需要显示发送人的昵称,自己发送的消息,不需要显示昵称。所以在设置约束的方法中得判断消息的发送者是谁,根据这个判断结果来决定昵称的约束形式。

    我优化后的处理方法是:通过cell的reuseIdentifier把消息发送者的信息传进来,这样就可以在执行setMessageModel:前获得消息发送者的信息。系统的updateConstrains或是自己写的设置约束方法的首次调用都会在setMessageModel:前执行。所以,setMessageModel:就不需要再主动调用约束设置方法。

    约束设置方法执行次数少了,效率明显会提高。


总结

    上述的问题可以简述为:在我们自己程序设计优化度不够或者一些特殊情景下,UITableView-FDTemplateLayoutCell与Masonry结合使用会导致Masonry设置约束多次执行,从而降低了程序运行效率、界面流畅度下降。

    解决办法:尽可能减少设置约束的方法的调用次数。

    上面讲了使用cell的reuseIdentifier提前传进来了关键参数。以后还可能遇到不能用reuseIdentifier传进来的关键参数,那就得想别的办法。只要不会增加设置约束方法执行次数就OK。 

你可能感兴趣的:(iOS开发)