美文网首页项目调优
IOS中使用AsynDisplayKit优化项目

IOS中使用AsynDisplayKit优化项目

作者: 寻找最亮的光 | 来源:发表于2018-03-20 17:13 被阅读65次

    前言

    在学习别人文章的时候做一个记录,免得在需要的时候找不到。本文主要记录原理性的内容,也会包含一些代码,具体使用请看文章。先把文章地址贴出来

    AsyncDisplayKit2.0教程上 

    AsyncDisplayKit2.0教程下

    这篇文章中的例子可以直接运行,另外的可以自己查看 AsyncDisplaykit2.0

    安装

    项目使用CocoaPods安装AsynDisplayKit,在Pod文件中输入安装

    source 'https://github.com/CocoaPods/Specs.git'

    target "AsyncDisplayKitForMit" do

    pod 'AsyncDisplayKit'

    end

    使用介绍

    在主线程中进行的一些大量操作包括:

    计算大小和布局:包括 -heightForRowAtIndexPath: 或对 UILabel 上进行 -sizeThatFits 调用,以及大量的自动布局约束的解析。

    图片解码:在一个 Image View 上使用 UIImage 就意味着要进行图片数据的解码。

    绘图:复杂文本以及手动绘制渐变色和阴影。

    对象生命周期:创建、操作和销毁系统对象(比如创建一个 UIView)。

    在正确使用的情况下,AsynDisplayKit 默认允许你以异步方式操作所有的计算大小、布局和绘图操作。不需要进行任何其它的优化,App 就能够大量减少需要在主线程上进行的工作。

    ASDisplayNode 简介

    ASDisplayNode 是 ASDK 的核心类,甚至可以说是“心脏”,就像 MVC 中的 view,可以看做是另一种 UIView 或 CALayer。理解一个“节点”对象的最好方法是参考 UIView 和 CALayer 的关系,你对此应该很熟悉了。

    在一个 iOS App 中,屏幕上的每一个对象都表示了一个 CALayer 对象。UIView 私底下会创建和拥有一个 CALayer,通过这个 CALayer 来感知触摸或其他功能。UIView 自身并不是 CALayer 子类。相反,它包含了一个 CALayer 对象,并为它添加了一些功能。

    这种概念也沿袭进了 ASDisplayNode:你可以认为它包含了一个 view,就好比 view 包含了一个 layer。

    将节点通过一个普通的 View 放到表格上,最终使它们能够从后台队列中创建和配置,默认情况下,它们会被异步渲染。

    幸运的是,这个 API 处理节点的方式和使用 UIView 或 CALayer 差不多。所有的 View 属性都可以在节点类上找到相同的属性。你还可访问底层的 view 或 layer——就像你可以通过 .layer 访问 UIView 的 layer 一样。

    节点容器

    要让节点对象尽可能地提升性,必须将它和 4 个容器类协同工作。 

    这 4 个容器类分别是:

    ASViewController: 一个 UIViewController 子类,允许你创建节点并进行管理。

    ASCollectionNode 和 ASTableNode: 对应于 UICollectionView 和 UITableView 的 Node 子类,封装了其底层细节。

    ASPagerNode: 一个 ASCollectionNode 子类,封装了扫动手势,对应于 UIKit 的 UIPageViewController。

    这也太简单了,但真正的秘密其实来自于 ASRangeController,这 4 个类都会通过它来影响所包含的节点的行为。现在,请听我说,暂且将那些内容保留到后面解释。

    使用

    a:导入框架 #import <AsyncDisplayKit/AsyncDisplayKit.h>

    b:声明tabelNode属性

    @property (strong, nonatomic) ASTableNode *tableNode;

    c:初始化容器,设置 TableNode 的数据和委托

    和 UITableView 一样,ASTableNode 也使用了数据源和委托来获得相关信息。Table Node 的 ASTableDataSource 和 ASTableDelegate 协议和 UITableViewDataSource 和 UITableViewDelegate 协议非常类似。事实上,它们的方法定义都很像,比如 -tableNode:numberOfRowsInSection:。当然,这两套协议也不是完全没有区别,因为 ASTableNode 的行为和 UITableView 多少还是有一点不同。

     _tableNode = [[ASTableNode alloc]initWithStyle:UITableViewStylePlain];

       self.tableNode.dataSource = self;

       self.tableNode.delegate = self;

       self.tableNode.view.separatorStyle = UITableViewCellSeparatorStyleNone;

       [self.view addSubnode:self.tableNode];

    d:然后,修改 -viewWillLayoutSubviews 方法:

    - (void)viewWillLayoutSubviews {  

    [superviewWillLayoutSubviews];

    self.tableNode.frame = self.view.bounds;

    }

    到现在相当于创建好了tableview并设置好其frame,显示cell需要再实现其数据源方法

    e:遵守数据源相关协议

    @interface AnimalTableController()<ASTableDataSource,ASTableDelegate>

    f:实现两个显示前重要的协议

    - (NSInteger)tableNode:(ASTableNode *)tableNode numberOfRowsInSection:(NSInteger)section { //返回多少行

      return self.animals.count;

    }

    然后,ASTableNodes 返回 cell 的方式和 UITableView 有所不同。将 -tableView:cellForRowAtIndexPath: 方法替换为:

     (ASCellNodeBlock)tableNode:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(NSIndexPath*)indexPath {

    RainforestCardInfo *animal  = self.animals[indexPath.row];

    ASCellNode *(^cellNodeBlock)() = ^ASCellNode *() {

            TableViewNodeCell *cellNode = [[TableViewNodeCell alloc] initWithHaiTao:haiTaoStyle];

            return cellNode;

        };

    return cellNodeBlock;

    }

    代码解释如下:

    TableViewNodeCell继承自ASCellNode,一个 ASCellNode 等同于 UITableViewCell 或 UICollectionViewCell。尤其要注意这个方法返回的是一个 ASCellNodeBlock。因为一个 ASTableNode 在内部维护了所有的 cell,为每个 cell 的 Index Path 指定了一个块,这样当需要的时候就能够异步地初始化所有 cell。 

    首先,你需要获得一个数据模型对象,以便渲染这个 cell。这已经是固定的套路了。获取数据,然后将它传给后面的闭包。IndexPath 在闭包中不需要,这个例子中在闭包被调用之前数据就会先发生改变。

    然后返回一个闭包,闭包中返回的类型必须是 ASCellNode。

    不需要关心 cell 重用的问题,因此只需要实例化一个 cell。注意,你返回的是一个 CardNode 而不是 CardCell。

    这里有一点要注意。你可能也注意到了,使用 ASDK 的时候 cell 不会进行重用。

    g:相信你也知道了,在使用 UITableView 的时候通常都需要实现一个 -tableView:heightForRowAtIndexPath: 方法。这是因为 UIKit 是通过这个委托方法来计算每个 cell 的高度的。

    ASTableDelegate 中没有 -tableView:heightForRowAtIndexPath: 方法。如果使用 ASDK, 所有的 ASCellNodes 都自己负责计算它们的大小。不需要提供一个固定的高度,你可以为每个 cell 指定一个最大尺寸和最小尺寸。这个例子中,你需要让每个 cell 至少占据屏幕 2/3 的高度。

    现在我们暂时不讨论这个,细节会在第二部分进行讨论。 

    现在,将 -tableView:heightForRowAtIndexPath: 方法替换为:

    - (ASSizeRange)tableView:(ASTableView*)tableNode  constrainedSizeForRowAtIndexPath:(NSIndexPath*)indexPath { 

     CGFloat width = [UIScreen mainScreen].bounds.size.width;  

    CGSizemin= CGSizeMake(width, ([UIScreen mainScreen].bounds.size.height/3) *2);  CGSizemax= CGSizeMake(width, INFINITY);

    returnASSizeRangeMake(min,max);

    }

    //剩下的重要内容就在自定义ASCellNode中了,包括里面的控件创建与布局。

    相关文章

      网友评论

        本文标题:IOS中使用AsynDisplayKit优化项目

        本文链接:https://www.haomeiwen.com/subject/jssbqftx.html