欢迎有兴趣的朋友,参与我的美女同事发起的活动《51天吃掉大象》,该美女真的很疯狂,希望和大家一起坚持51天做一件事情,我加入这个队伍,希望坚持51天每天写一篇技术文章。关注她的微信公众号:zhangmanyuheart了解更多吧。
前言:今天学习了半天的网络和多线程的内容,然后想起其中的例子和我曾经看过的一篇外文的内容非常相似,它们都对我理解网络和多线程有极大的帮助,因此决定找来这篇文章翻译作为的坚持51天吃掉大象(写技术文章)的第二天的技术文章,也对这自己今天的学习做个总结。原文出处:http://www.raywenderlich.com/76341/use-nsoperation-nsoperationqueue-swift
咳,不得不说我们这些年轻人都是电子产品重度使用者,也都经历过因为软件卡顿而气的恨不能够一句咒语毁灭地球或者一巴掌毁灭自己。
现在有价值的app都需要能够多任务同时进行来满足用户的需求,但有个矛盾点就是:主线程不能执行耗时操作同时又保证及时响应用户操作,因此对我们开发者而言,就需要毁灭自己之前也要把这个问题解决,这样才能拯救人类。
我们开发者可以通过并发的方式将一些操作放到主线程之外的线程上执行,从而不影响交互界面保持响应能力。
本文将介绍NSOperation(操作) 和 NSOperationQueue(操作队列),来实现并发。教程从一个不使用并发技术的app样例开始,您下载下来试运行下就会明白操作它是多么痛苦的事情,确实又慢又卡,然后我们跟着教程一步一步改善它,最终效果会非常的nice,用起来会流畅许多。
让我们开始吧!
关于起始程序
样例主要功能就是通过tableview,展示一些添加滤镜效果的的图片。图片从网络上下载,然后添加滤镜,最后显示在表格视图上。
模型示意图如下:
大概对app样例了解之后,就可以下载样例下来体验一把。下载地址:http://cdn5.raywenderlich.com/wp-content/uploads/2014/10/ClassicPhotos-Starter63.zip
编译并运行。你将会看到下图相似的效果,app显示一个图片列表,但是向下滑动,就会发现非常的卡顿有木有。
看看代码你就会发现几乎所有的操作都写在 ListViewController.swift类中,而且主要集中在tableView(_:cellForRowAtIndexPath:)方法中。该方法主要实现以下两个作用。
1.从互联网上加载图片。尽管实现起来容易,但是app必须要等待图片加载完成才能继续操作。
2.使用core image 给图片添加滤镜。
所有这些工作都是在主线程上执行,然而主线程又需要响应用户操作。而加载图片和添加滤镜本身又是耗时操作,所以不可避免就会导致无法及时响应用户的操作。我们可以在程序调试过程中,通过 Debug navigator (Command-6)查看cpu和内存的使用情况,如图:
从图中可以看到,所有的耗时操作都是在主线程上。
了解了这个app之后,我们现在开始来着手改进它,不过在开始之前我们先了解一些概念。
1.任务:一个需要app完成的一件简单的事情或操作。
2.线程:操作系统提供给的一种机制,该机制允许多个指令同时在一个程序中运行。
3.进程。一大段可执行的代码,一般会有多个线程组成。
下面这个图可以很好的解释进程,线程和任务之间的关系。
从图中可以了解到,一般一个进程会包含一个或者多个线程,一个线程也会包含一个或者多个任务。
NSOperation操作 和 Central Dispatch(GCD)比较
NSOperation操作 和 Central Dispatch(GCD)是在GCD之上做了一次更高层级的封装,苹果也推荐我们使用更高级别的方法,当然也需要根据实际需要决定。
以下是对两者的快速比较,它会帮助你决定何时何地去使用GCD或者NSOperation和NSOperationQueue。
1.GCD提供了一个轻量级的执行多个并发任务单元的解决方案。我们开发者不需要关心多个任务之间是如何调度的,因为系统会自动帮我们调度。不过也正因为如此,我们想更好的控制代码块的执行依赖顺序也变的头疼了,取消和暂停一个任务也非常的困难。
2.NSOperation操作。可能比GCD稍微要难使用点,但也意味着你可以更好的控制多个任务的依赖关系从而控制任务的执行顺序,取消和暂停。
好了,现在我们就来通过NSOperation技术来优化我们的程序吧。