这篇文章是对阿里、字节:一套高效的iOS面试题 这片文章中关于多线程的几个问题的回答。如有问题,欢迎大家指正。

  1. iOS开发中有多少类型的线程?分别对比
    1. pthread:

      1. 一套通用的多线程API

      2. 适用于 Unix / Linux / Windows 等系统

      3. 跨平台\可移植

      4. 使用难度大|C|程序员管理|几乎不用

    2. NSThread:

      1. 使用更加面向对象

      2. 简单易用,可直接操作线程对象|OC|程序员管理|偶尔使用

    3. GCD:

      1. 旨在替代NSThread等线程技术

      2. 充分利用设备的多核

      3. 基于 C 的底层的 API|C|自动管理|经常使用

    4. NSOperation:

      1. 是基于 GCD 实现的 Objective-C API

      2. 比GCD多了一些更简单实用的功能

      3. 使用更加面向对象|OC|自动管理|经常使用

  2. GCD有哪些队列,默认提供哪些队列

    1. 主队列:dispatch_get_main_queue

    2. 全局队列:dispatch_get_global_queue

    3. 串行队列:dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);

    4. 并发队列:dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);

  3. GCD有哪些方法api
    1. dispatch_queue_create                        //通过dispatch_queue_create函数可生成Dispatch Queue

    2. Main Dispatch Queue/Global Dispatch Queue     //Main Dispatch Queue是在主线程中执行的Dispatch Queue。因为主线程只有一个,所以Main Dispatch Queue自然就是Serial Dispatch Queue。Global Dispatch Queue是所有应用程序都能够使用的Concurrent Dispatch Queue。没有必要通过dispatch_queue_create函数逐个生成Concurrent Dispatch Queue。只要获取Global Dispatch Queue即可。

    3. dispatch_set_target_queue                    //dispatch_queue_create函数生成的Dispatch Queue不管是Serial Dispatch Queue还是Concurrent Dispatch Queue,都使用与默认优先级Global Dispatch Queue相同执行优先级的线程。而变更生成的Dispatch Queue的执行优先级要使用dispatch_set_target_queue函数。

    4. dispatch_after                                //想在指定时间后执行处理的情况,可使用dispatch_after函数来实现。

    5. Dispatch Group                                //在追加到Dispatch Queue中的多个处理全部结束后想执行结束处理。

    6. dispatch_barrier_async                        //dispatch_barrier_async函数会等待追加到Concurrent Dispatch Queue 上的并行执行的处理全部结束之后,再将指定的处理追加到该Concurrent Dispatch Queue中。然后在由dispatch_barrier_async函数追加的处理执行完毕后,Concurrent Dispatch Queue才恢复为一般的动作。追加到该Concurrent Dispatch Queue的处理又开始并行执行。

    7. dispatch_sync                                 //将指定的block同步追加到指定的Dispatch Queue中。在追加block结束之前,dispatch_sync函数会一直等待。

    8. 一旦调用dispatch_sync函数,那么在指定的处理执行结束之前,该函数不会返回。dispatch_sync函数可简化源代码,也可说是简易版的dispatch_group_wait函数。

    9. 但也容易引起死锁。

    10. dispatch_apply                                //dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联API,该函数按指定的次数将指定的Block追加到指定的Dispatch Queue中,并等到全部的处理执行结束

    11. dispatch_suspend / dispatch_resume            //dispatch_suspend函数挂起指定的Dispatch Queue;dispatch_resume函数恢复指定的Dispatch Queue

    12. dispatch_once                                 //dispatch_once函数是保证在应用程序执行中只执行一次指定处理的API

    13. 参考文章

  4. GCD主线程 & 主队列的关系

    • 主队列是一个任务执行队列,是一个线性队列,每个node是一个task,主线程在空闲时会去主队列里看看有没有要执行的任务,pop出来执行

  5. 如何实现同步,有多少方式就说多少
    • OSSpinLock

    • os_unfair_lock

    • pthread_mutex

    • dispatch_semaphore

    • NSLock

    • NSRecursiveLock

    • NSCondition

    • NSConditionLock

    • @synchronized

    • 参考文章

  6. dispatch_once实现原理
  7. 什么情况下会死锁

    • 所谓死锁,通常指有两个线程T1和T2都卡住了,并等待对方完成某些操作。T1不能完成是因为它在等待T2完成。但T2也不能完成,因为它在等待T1完成。于是大家都完不成,就导致了死锁(DeadLock)。

    • 产生死锁的条件:

      • 互斥条件:一个资源每次只能被一个进程使用。

      •  请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

      • 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

      • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

      • 这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

  8. 有哪些类型的线程锁,分别介绍下作用和使用场景
    • 自旋锁 OSSpinLock

    • 互斥锁 os_unfair_lock 、pthread_mutex

    • 条件锁 NSConditionLock

    • 递归锁 NSRecursiveLock

    • 临界区低端锁nslock

    • 参考文章

  9. NSOperationQueue中的maxConcurrentOperationCount默认值

    • 答案:-1

  10. NSTimer、CADisplayLink、dispatch_source_t 的优劣
    • NSTimer
      • 存在延迟

      • 必须加入Runloop

      • 容易出现循环引用

    • CADisplayLink
      • CADisplayLink适合做界面的不停重绘,比如视频播放的时候需要不停地获取下一帧用于界面渲染。
    • dispatch_source_t
      • 时间准确

      • 可以使用子线程,解决定时间跑在主线程上卡UI问题

      • 需要将dispatch_source_t timer设置为成员变量,不然会立即释放

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐