AsyncDisplayKit - 加快 UI 响应性能
TrinidadTri
8年前
<p>AsyncDisplayKit 是 非死book 推出的一个开源库, 主要针对于最大化 UI 的响应速度。</p> <h2>关于 AsyncDisplayKit</h2> <p>AsyncDisplayKit 是 非死book 开发 Paper 的团队项目中产出的副产品。 虽然 Paper 这个项目没能取得预期的成绩, 但却留下了 AsyncDisplayKit 这个开源库。 AsyncDisplayKit 主要用于加快 iOS app 中 UI 相应的性能。</p> <p>iOS 本身对 UI 响应速度的优化做的非常好, 比如通过 RunLoop 来控制主线程的优先级, 优先响应用户操作。 这一点大家在拖动诸如 UITableView 这类的控件时可能会注意到,假如你在拖动的时候同时在后台请求图片之类的数据, 在你放手之前, 这些后台网络请求会被阻塞。 这也是 iOS 对于 UI 响应做的一个优化。 这个优化是通过 UITrackingRunLoopMode 做到的。 </p> <p>再回到 AsyncDisplayKit , 它对 iOS 的 UI 响应做了进一步优化。 其中一个特点就是允许在 <strong>非主线程操作 UI 控件</strong> 。 是的,你没看错。 必须在主线程操作 UI 控件这个概念几乎成了 iOS 以及大多数客户端开发的定律。如果在 iOS 中的非主线程操作 UI, 就会导致一系列奇怪的结果,甚至造成应用 Crash。</p> <p>不过, AsyncDisplayKit 确实能够提供这个能力。 这样你就可以让主线程更加有效率。 比如,你可以将 UIImage 加载图片的操作放到异步线程中, 并且在这个异步线程中设置图片, 调整 UI 组件的 frame 等等。</p> <p>那么 AsyncDisplayKit 是怎么能做到呢? 它依然运用的是 RunLoop 上的特性。</p> <h2>使用 AsyncDisplayKit</h2> <p>AsyncDisplayKit 可以通过 Carthage 集成, 编辑 Cartfile:</p> <pre> <code class="language-objectivec">github "非死book/AsyncDisplayKit" </code></pre> <p>然后运行:</p> <pre> <code class="language-objectivec">carthage update </code></pre> <p>集成完毕后, 就可以在项目中使用了, 如果使用 Swift, 首先需要在 BridgingHeader 中引入:</p> <pre> <code class="language-objectivec">#import <AsyncDisplayKit/AsyncDisplayKit.h> </code></pre> <p>AsyncDisplayKit 针对 UIKit 的每一个控件都定义了对应的封装, ASImageNode 对应 UIImageView 。 完整的对应关系可以参考这张图:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/4b67292dda2ded9b3376c7d17afa6b30.jpg"></p> <p>从图中可以看出, AsyncDisplayKit 将 View 映射成了 Node , 比如我们要在 UI 上面显示一个图片, 可以这样:</p> <pre> <code class="language-objectivec">class ViewController: ASViewController<ASDisplayNode> { override func viewDidLoad() { super.viewDidLoad() let imageNode = ASImageNode() self.view.addSubnode(imageNode) DispatchQueue.global().async { imageNode.image = UIImage(named: "icon") imageNode.frame = CGRect(x: 100, y: 100, width: 150, height: 150) } } } </code></pre> <p>这里为了简化,将异步线程的代码写在里一起。 我们在主线程中创建了 ASImageNode 然后将它添加到了视图结构中, 注意使用的是 addSubnode 方法。 大家仔细看一下,可以发现我们的 ViewController 继承自 ASViewController 。</p> <p>AsyncDisplayKit 还对控制器做了处理。 我们需要使用这些控制器才能开启 AsyncDisplayKit 的全部特性。</p> <p>接下来我们用了一个 DispatchQueue 异步的加载图片,并设置 ImageNode 的 frame , 这些都是在异步线程进行的。</p> <p>运行程序你会发现一切都正常的执行了。 并没有因为在异步线程操作 UI 而产生问题。 至于 AsyncDisplayKit 是如何做到这一点的, 前面给大家推荐的文章中详细的做了讲解。</p> <h2>智能预加载</h2> <p>智能预加载是我翻译过来的名字, 原名叫做 Intelligent Preloading , 是 AsyncDisplayKit 针对类似 UIScrollView, UITableView 这些可滑动的组件做的一个优化。 Intelligent Preloading 也是充分运用 AsyncDisplayKit 的异步 UI 操作能力,在视图上下滑动的时候,进行一些更加优化的动态处理。 因为我们开发的大多数 App 都会用到诸如 UITableView 这样的滑动组件,所以这个特性对于我们开发的 App 还是很有帮助的。</p> <h2>结语</h2> <p>以上就是对 AsyncDisplayKit 给大家做的简要介绍了,它提供的这些特性对于提升 App 的 UI 性能还是比较有帮助的。 如果你的 App 正面临这方面的问题, 不妨可以试一下 AsyncDisplayKit 。 当然,它的全部特性还是比较复杂的, 这里面给大家只做了一个简要的介绍。</p> <p> </p> <p> </p> <p>来自:http://www.swiftcafe.io/2016/12/12/asdk/</p> <p> </p>