源码地址
Examples
学习资源

Texture 的组成

概述:

提到Texture大家可能会比较陌生,但是如果说AsyncDisplayKit估计搞iOS的很多人都会或多或少听到过,我们知道UIKit大多数的布局绘制工作都必须在主线程完成。Texture 中的Node是线程安全的我们可以在后台子线程中完成实例创建整个布局的计算。我们知道如果要保证界面流畅必须保证每秒60帧的帧率,也就是说要在16ms时间内完成所有的布局和绘制代码。但是主线程一般还有如事件相应之类的任务需要处理,所以往往留给布局绘制的时间通常小于10毫秒甚至更少。所以Texture的思路就是将Node设计成线程安全的,并将那些例如node创建,图片解码,文本尺寸计算,渲染等操作可以移到后台子线程的尽量移到后台线程,只有在必须在主线程处理的时候才切换到主线程。

Node Vs UIView Vs CALayer:

Node,UIView,CALayer 三者的关系如下图所示,详细的介绍会在后面详细张开来介绍。

节点 与 节点容器

Texture中提供的节点有如下几种:

Texture UIView
ASDisplayNode 等效于UIView,所有Node的父类
ASCellNode 等效于UITableViewCell和UICollectionViewCell,用于ASTableNode, ASCollectionNode和ASPagerNode
ASScrollNode 等效于UIScrollView,它用于创建一个包含其他节点的自定义滚动区域
ASEditableTextNode 等效于UITextView
ASTextNode 等效于UILabelView
ASImageNode,ASNetworkImageNode,ASMultiplexImageNode 等效于UIImageView
ASVideoNode 等效于AVPlayerLayer
ASVideoPlayerNode 等效于UIMoviePlayer
ASControlNode 等效于UIControl
ASButtonNode 等效于UIButton
ASMapNode 等效于MKMapView

这些节点和UIVi布局和的区别是所有的node在后台子线程中进行布局和显示,所以主线程可以预留有充足的时间来相应用户交互事件。

Texture中提供的节点容器有如下几种:

Texture UIView
ASCollectionNode 等效于UICollectionView
ASTableNode 等效于UITableView
ASPagerNode 等效于UIPageViewController
ASViewController 等效于UIViewController
ASNavigationController 等效于UINavigationController
ASTabBarController 等效于UITabBarController

那么节点容器和UIKit中的普通的视图容器优点在哪里呢?这就要提到Texture的智能预加载功能,在每个节点添加到一个滚动的或者翻页界面的时候,在界面滚动的时候,节点的interfaceState会不断改变,这个interfaceState属性是由ASRangeController来完成更新工作的,如果在节点容器外使用节点的话ASRangeController将不会更新节点的状态。这将导致界面上的节点不会感知到界面状态的改变,从而导致界面上闪烁的现象。

状态 描述
预加载 这个阶段是从网络或者磁盘加载资源的阶段
显示 这个阶段主要是完成文本珊格化和图片解码工作
可见 节点出现在界面上

这些阶段都有对应的回调节点:

预加载阶段

-didEnterPreloadState
-didExitPreloadState

显示阶段

-didEnterDisplayState
-didExitDisplayState

可见阶段

-didEnterVisibleState
-didExitVisibleState
布局引擎

Texture中不能使用AutoLayout布局方式,它内部实现了一套基于FlexBox的模式的布局引擎,Flex布局模式目前已经成为了前端UI框架的标配,目前比较流行的Flutter,SwiftUI都有它的影子。

Texture的布局性能介于手动布局和Auto Layout方式布局,并且明显快于Auto Layout,这主要是因为布局可以在后台线程中进行计算,所以不会干扰到用户交互,并且由于布局结果是不可变的数据结构,因此可以在后台预计算和缓存它们。

Texture的布局涉及到两个概念:

  • Layout Specs (布局规范)
Layout Specs 充当布局容器的角色,主要用于放置Layout Elements ,它主要关注的是Layout Elements 之间的位置关系。
Texture 提供了如下的布局容器:
ASWrapperLayoutSpec
ASStackLayoutSpec
ASInsetLayoutSpec
ASOverlayLayoutSpec
ASBackgroundLayoutSpec
ASCenterLayoutSpec
ASRatioLayoutSpec
ASRelativeLayoutSpec
ASAbsoluteLayoutSpec
ASCornerLayoutSpec

  • Layout Elements (布局元素)
ASDisplayNodes 和 ASLayoutSpecs 都遵循ASLayoutElement协议,所以ASDisplayNodes 和 ASLayoutSpecs 都可以作为布局元素节点。

这里还需要了解的一个概念是布局元素的固有尺寸
有些元素在没有加载元素之前本身是有一个固有尺寸的,这体现在如果我们没有为它添加宽高,它本身就有一个固有宽高值这些Node元素包括:

ASImageNode
ASTextNode
ASButtonNode

反之某些元素在没有加载元素之前是没有尺寸数据的,因此在数据未加载之前可能需要我们给他指定一个宽高,这类元素有:

ASVideoNode
ASVideoPlayerNode
ASNetworkImageNode
ASEditableTextNode

资料汇总:

源码地址
官方文档地址
Examples
官方资源
iOS 保持界面流畅的技巧
使用 ASDK 性能调优 - 提升 iOS 界面的渲染性能
AsyncDisplayKit 即刻技术团队系列文章
AsyncDisplayKit近一年的使用体会及疑难点
AsyncDisplayKit 2.0 Tutorial: Getting Started
AsyncDisplayKit源码阅读笔记
AsyncDisplayKit(一)初识
ASDK源码剖析

Contents
  1. 1. Texture 的组成
  2. 2. 概述:
  3. 3. Node Vs UIView Vs CALayer:
  4. 4. 节点 与 节点容器
  5. 5. 布局引擎
  • 资料汇总: