AsyncDisplayKit - 加快 UI 响应性能

swift 发布于 2017年11月20日
关于 AsyncDisplayKit

AsyncDisplayKitFacebook 开发 Paper 的团队项目中产出的副产品。 虽然 Paper 这个项目没能取得预期的成绩, 但却留下了 AsyncDisplayKit 这个开源库。 AsyncDisplayKit 主要用于加快 iOS app 中 UI 相应的性能。

iOS 本身对 UI 响应速度的优化做的非常好, 比如通过 RunLoop 来控制主线程的优先级, 优先响应用户操作。 这一点大家在拖动诸如 UITableView 这类的控件时可能会注意到,假如你在拖动的时候同时在后台请求图片之类的数据, 在你放手之前, 这些后台网络请求会被阻塞。 这也是 iOS 对于 UI 响应做的一个优化。 这个优化是通过 UITrackingRunLoopMode 做到的。 有兴趣的同学可以参考苹果关于 RunLoop 的文档, https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

再回到 AsyncDisplayKit, 它对 iOS 的 UI 响应做了进一步优化。 其中一个特点就是允许在非主线程操作 UI 控件。 是的,你没看错。 必须在主线程操作 UI 控件这个概念几乎成了 iOS 以及大多数客户端开发的定律。如果在 iOS 中的非主线程操作 UI, 就会导致一系列奇怪的结果,甚至造成应用 Crash。

不过,AsyncDisplayKit 确实能够提供这个能力。 这样你就可以让主线程更加有效率。 比如,你可以将 UIImage 加载图片的操作放到异步线程中, 并且在这个异步线程中设置图片, 调整 UI 组件的 frame 等等。

那么 AsyncDisplayKit 是怎么能做到呢? 它依然运用的是 RunLoop 上的特性, 关于深入的原理, 可以参看这篇文章 http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/

使用 AsyncDisplayKit

AsyncDisplayKit 可以通过 Carthage 集成, 编辑 Cartfile:

github "facebook/AsyncDisplayKit"

然后运行:

carthage update

集成完毕后, 就可以在项目中使用了, 如果使用 Swift, 首先需要在 BridgingHeader 中引入:

#import <AsyncDisplayKit/AsyncDisplayKit.h>

AsyncDisplayKit 针对 UIKit 的每一个控件都定义了对应的封装, ASImageNode 对应 UIImageView。 完整的对应关系可以参考这张图:

从图中可以看出, AsyncDisplayKitView 映射成了 Node, 比如我们要在 UI 上面显示一个图片, 可以这样:

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)

        }

    }

}

这里为了简化,将异步线程的代码写在里一起。 我们在主线程中创建了 ASImageNode 然后将它添加到了视图结构中, 注意使用的是 addSubnode 方法。 大家仔细看一下,可以发现我们的 ViewController 继承自 ASViewController

AsyncDisplayKit 还对控制器做了处理。 我们需要使用这些控制器才能开启 AsyncDisplayKit 的全部特性。

接下来我们用了一个 DispatchQueue 异步的加载图片,并设置 ImageNode 的 frame, 这些都是在异步线程进行的。

运行程序你会发现一切都正常的执行了。 并没有因为在异步线程操作 UI 而产生问题。 至于 AsyncDisplayKit 是如何做到这一点的, 前面给大家推荐的文章中详细的做了讲解。

智能预加载

智能预加载是我翻译过来的名字, 原名叫做 Intelligent Preloading, 是 AsyncDisplayKit 针对类似 UIScrollView, UITableView 这些可滑动的组件做的一个优化。 Intelligent Preloading 也是充分运用 AsyncDisplayKit 的异步 UI 操作能力,在视图上下滑动的时候,进行一些更加优化的动态处理。 因为我们开发的大多数 App 都会用到诸如 UITableView 这样的滑动组件,所以这个特性对于我们开发的 App 还是很有帮助的。

结语

以上就是对 AsyncDisplayKit 给大家做的简要介绍了,它提供的这些特性对于提升 App 的 UI 性能还是比较有帮助的。 如果你的 App 正面临这方面的问题, 不妨可以试一下 AsyncDisplayKit。 当然,它的全部特性还是比较复杂的, 这里面给大家只做了一个简要的介绍。如果想要更多的了解,大家还可以参看 AsyncDisplayKit 的官网: http://asyncdisplaykit.org/


如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~

本站文章均为原创内容,如需转载请注明出处,谢谢。
关注微信公众号
发现更多精彩
swift-cafe