微信号:qzonemobiledev

介绍:QQ空间终端开发团队官方账号,分享QQ空间在Android、iOS、H5等平台的开发经验、技术实践以及一些围绕技术研发的话题.

ComponentKit框架解析之一—初识CK

2017-11-17 15:10 tomgwtang

一、简介

    ComponentKit是基于React思想的一个iOS原生UI开发框架。它通过函数式和声明的方式构建UI。目前用于Facebook的News Feed模块。
    我们先看一个简单Demo的Component实现

    这里,我们描述了一个组件,该组件由三个子组件和Flexbox排版组件构成,竖直从下往上依次排列,子组件间距为50pt。视觉如下

二、思想

    开发人员通过创建组件(描述UI的模板)的形式,描述UI应该长成什么样子。复杂UI根据单一职责,拆成若干组件,来描述整体UI的层次结构。将UI具体实现(包括创建,特征实现,排版管理)交由框架的基础服务实现。

由上述设计思想,引出ComponentKit 三大特点

  • 描述性
    如上面例子,相对传统的构建UI(手工创建,设置属性,计算布局)。这里我们只描述组件QZStackDemoComponent,竖直从下往上依次排列三个子组件,组件space为50,子组件又描述文本的颜色,字体。具体UI的创建和管理,交给框架基础服务。

  • 函数式
    数据的流动是单方向的。数据模型-->创建组件-->根据组件的描述生成更新UI。
    当组件的状态更新,将根据对应的状态重新构造一个新组件实例。ComponentKit 会重新比对新旧两个组件的差异,然后更新UI。

  • 组合
    复杂的UI实现,通过不同的单一职责的组件组合成复杂组件,然后交由框架实现。小的组件可以进行比较好的复用。如上例中的CKLineComponent,CKLabelComponent。

三、布局方式

    使用成熟的描述性的FlexBox布局方式,具体可以参考相应教程。我们只需要按照比较好理解的从左往由,从下往上,剧中,填充满等布局方式给出对应的描述,然后ComponentKit即可通过Flexbox的yoga布局引擎计算布局。

    例如实现元素在容器内由下往上排列布局伪代码如下

[CKFlexboxComponent
             newWithView:{}
             size:{}
             style:{
                 .direction = CKFlexboxDirectionVertical,
             }
             children:{
                 {Component0},
                 {Component1},
                 {Component2},
             }]

    这比使用传统基于frame的绝对布局和基于约束的AutoLayout布局要更容易理解和维护的多。

四、组件渲染过程

  • 创建Component实例,没有全局变量,线程安全。

  • 异步线程计算排版。

  • 根据组件描述,计算好的排版,创建和更新UI。

    这里虽然每次新建或者更新都会重建Component树,但是ComponentKit会计算新旧Component的差异,最小化更新UI。
    此外从Component树转换成UI,并不是每个Component都会创建UI元素,有的只是用于排版。如下图,5个Component只生成4个UI元素

    ComponentKit内部还会对已有的UI进行复用。如下图,只有Vidoe元素是重新生成,其他元素复用

五、优点

  • 开发人员不需要关心具体的描述实现,UI都是根据模板通过ComponentKit构建,简化了结构和思维的难度,也就意味着更少的 bug。

  • 对于列表(UICollectionView,UITableView)的支持很棒,可以用少量清爽的代码就可以构造出高性能的列表。

  • 复用性高,可以减少开发的业务代码量,Facebook声称用ComponentKit改版News Feeds模块减少了70%代码。

  • 可测试性高。

六、缺点

  • 对于不熟悉ObjC++语法的同学,会有一定学习成本。

  • 把 UI 变成各种 state 之间的演化,这样对于连续的行为不是很好处理。所以对复杂手势,复杂动画支持不友好。

  • ComponentKit 需要写 ObjC++,Swift 不支持 ObjC++ ,和Swift混编比较麻烦。



 
QQ空间终端开发团队 更多文章 Swift是猴还是猿? 一个ClassLoader引起的JNI链接错误 手Q人脸识别动画实现详解 关于 Block 中捕获 self 的分析 王辉|十亿级视频播放技术优化揭密
猜您喜欢 图片识别技术&数据抓取 周报08 | 你所知道的获取知识的高效途径? React Native应用如何实现60帧\/秒的流畅动画? 使用开源工具使OpenStack监控堆栈高可用 GRADLE 构建最佳实践