#写在最前面
最近发现自己学东西的效率好像高了,难道是因为写博客做笔记的原因吗?的确通过写博客来记录自己学习的成果能够加强自己对很多问题的理解。只有能够通过自己的语言将学习到的内容讲出来才是真的理解。所以以后看来要多写写。
#正文
##GCD是什么鬼
GCD,简单的来说就是苹果自己出的一套多核运算的解决方案。虽然苹果没有安卓那么多核心,但是并行化运算能够提高流程性是不可争辩的事实。GCD内部自动管理线程 的生命周期,不需要我们自己去手动管理。我们只需要调用对应的API就可以了。GCD是基于C语言开发的,不过由于使用了block,所以使用起来很方便。在了解GCD之前,我们需要了解一点多线程运行的原理。
基本概念
GCD中有两个重要的概念:任务 和 队列
- 任务。我们可以理解任务就是一个动作,放在GCD中就是一个代码块(block)。执行任务有两种,分别为同步执行 和 异步执行。同步和异步的区别其实很好理解。
同步执行
既是当前任务执行完前会阻塞当前进程,而异步执行
就不会。 队列。队列是用来存放任务的。我们可以理解为任务就是队列中排队等待执行。队列分为串行队列和并行队列。
- 串行队列,就像排队一样,严格遵守FIFO。
- 并行队列,同样执行FIFO。不同的是,取出来的任务会根据情况放到别的线程上。由于多个线程出队的时间间隔可能很短,所以容易认为是非FIFO的。不过即使这样,系统也会根据硬件条件来判断,并不一定会所有任务都在同时执行。
创建队列的操作如下图所示
创建任务如下如图所示
队列组
对列组就是将多个队列添加到一个组里。这样的方式使我们可以在队列里所有的任务都完成后收到一个通知方法。
1 | objective-c |
NSOperation 和 NSOperationQueue
NSOperation 和 NSOperationQueue是苹果对GCD的基于面向对象的完全封装,使其更容易理解。操作方式也更简单
- 将要执行的任务封装到一个
NSOperation
对象中 将任务添加到一个
NSOperationQueue
中此后系统将自动在执行任务。
添加任务
由于NSOperation是一个抽象类,所以不能直接封装任务。但是有两个子类用于封装任务:NSInvocationOperation
和 NSBlockOperation
。创建一个队列后,需要调动start()
方法来启动,默认在当前队列同步执行。同时队列提供cancel()
方法在中途取消任务。
- NSInvocationOperation 传入一个方法名。
- NSBlockOperation 传入一个代码块。
- 在NSBlockOperation中,有一个方法
addExecutionBlock
方法。这个方法使我们可以添加多个block到队列中。这些block将会并发执行**,将在主线程和其他的多个线程``执行任务
- 在NSBlockOperation中,有一个方法
###添加队列
多数时候,我们不希望当前线程被占用,因为会影响到UI的流畅性(UI永远在主线程上)。因此我们需要创建新的队列。只要我们添加任务到队列上,就会自动调用任务的start()
方法。如果任务在其他队列上,那么他就会在其他线程上并行执行。
我们发现,NSOperationQueue
并没有设置串行和并行队列的问题,那么NSOperationQueue
是怎么确定队列的类型的呢。苹果通过封装巧妙的使调用者不需要特意的去注意队列的性质,只需要设置NSOperationQueue
中的maxConcurrentOperationCount
– 最大并发数就可以了。
##总结
在上篇block的文章中也谈到了block在gcd的中的应用。通过gcd,我们可以最大化的去使用硬件的性能,避免出现卡顿的现象。多线程用的好不好,也基本上代表了一个开发者的能力水平。虽然多线程编程有许多坑,但只有跨过一个个坑,才能变成大牛,不是吗?