iOS 开发高手课
戴铭
前滴滴出行技术专家
42934 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
用户故事 (1讲)
iOS 开发高手课
15
15
1.0x
00:00/00:00
登录|注册

17 | 远超你想象的多线程的那些坑

解决方案:使用串行队列管理数据库操作
数据读写操作中的风险
使用CFRunLoopRef的CFRunLoopRun和CFRunLoopStop
使用NSRunLoop的runUntilDate:和runMode:beforeDate
NSURLSession的替代方案
NSURLConnection的设计缺陷
系统强杀
整体性能降低
CPU消耗
线程创建的内存开销
GCD
解决方案
AFNetworking 2.0
分享曾经遇到的多线程问题及解决方法
替换FMDatabase为FMDatabaseQueue并查看内存消耗情况
避免数量不可控的并发处理
控制并发数量
常驻线程不要滥用
内存问题
并发
常驻线程
课后小作业
建议
问题
多线程技术

该思维导图由 AI 生成,仅供参考

你好,我是戴铭。今天,我们一起来聊聊 iOS 开发中,使用多线程技术会带来的那些问题。
我们可以先来试想这么一个场景,如果没有多线程技术,那么我们要对一张照片进行滤镜处理时,就只能由主线程来完成这个处理。可想而知,这时候主线程阻塞了,其他的任何操作都无法继续。
解决这个问题的方法,就是再多创建一个线程来进行滤镜处理的操作,这样主线程就可以继续执行其他操作。这,也就是我们今天要说的多线程技术了。
目前,在 iOS 开发中,我们经常会用到系统提供的方法来使用多线程技术开发 App,期望可以充分利用硬件资源来提高 App 的运行效率。
但是,我们不禁会想到,像 UIKit 这样的前端框架并没有使用多线程技术。而 AFNetworking 2.0(网络框架)、FMDB(第三方数据库框架)这些用得最多的基础库,使用多线程技术时也非常谨慎。
那么,你有没有想过为什么 UIKit 不是线程安全的,UI 都要在主线程上操作。
在 AFNetworking 2.0 中,把每个请求都封装成了单独的 NSOperationQueue,再由 NSOperationQueue 根据当前的 CPU 数量和系统负载来控制并发。那么,为什么 AFNetworking 2.0 没有为每个请求创建一个线程,而只是创建了一个线程,用来接收 NSOperationQueue 的回调呢?
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了iOS开发中使用多线程技术可能带来的问题,重点关注了常驻线程和并发方面的挑战。文章首先介绍了多线程技术的应用场景和常见的多线程库,强调了谨慎使用多线程技术的重要性。随后,重点讨论了常驻线程的问题,并以AFNetworking 2.0为例,说明了常驻线程的创建和存在的问题,以及使用NSURLSession替代NSURLConnection来避免常驻线程的做法。此外,还详细阐述了并发带来的内存问题,并提出了解决方案,强调了避免常驻线程问题的建议。总的来说,本文对多线程技术的问题和解决方案进行了详细的阐述,对开发者具有一定的参考价值。文章内容深入浅出,对多线程技术的问题和解决方案进行了详细的阐述,对开发者具有一定的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《iOS 开发高手课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(32)

  • 最新
  • 精选
  • 烩面
    老师问个问题:一个 app 有线程数量的限制吗?或者说,通常情况下,线程数达到多少就被系统 kill 掉了?

    作者回复: 不要超过64个

    2019-04-18
    2
    7
  • Emir
    多线程并发数量和可控需要怎么做到呢?老师应该讲一下方案、不能怕并发多就改成串行,多线程的意义呢?

    作者回复: 不是说不要用而是不要滥用,比如需要短时间内快速处理数据的情况,使用多线程正好可以利用多核性能来高效完成任务。很多三方库之所以使用串行的原因就是为了避免大部分情况下多线程技术被滥用。

    2019-04-18
    5
  • Geek_0ce7bf
    在 AFNetworking 2.0 中,把每个请求都封装成了单独的 NSOperationQueue。大佬你这句话写错了吧?每个请求都封装成了单独的 NSOperation才对吧?????

    作者回复: 是的

    2019-04-20
    4
  • Dashing
    按照我粗浅的理解,串行队列背后也是一个线程,貌似跟常驻线程也差不多

    作者回复: 常驻线程是一直存在的

    2019-04-22
    2
    2
  • 加温后的啤酒
    老师 文中的这段代码哪里有创建新线程? [NSThread currentThread] 这个方法不是过去当前线程吗?为什么会创建一个新的? + (void)networkRequestThreadEntryPoint:(id)__unused object { @autoreleasepool { // 先用 NSThread 创建了一个线程 [[NSThread currentThread] setName:@"AFNetworking"]; // 使用 run 方法添加 runloop NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; [runLoop run]; } }

    作者回复: 这个方法所在的线程是新创建的

    2019-04-19
    3
    1
  • sacrifice
    老师,我for循环10000次创建子线程,内存消耗的也不明显啊

    作者回复: 子线程里做了什么?

    2019-04-18
    3
    1
  • drunkenMouse
    常驻线程和单线程不是一个概念,但是AFN2.0的操作不是都在一个常驻线程吗,那这个常驻线程算不算是一个一直存活的子线程?

    作者回复: 算

    2019-04-19
  • tripleCC
    关于NSURLConnection和URLSession那块有一个地方讲的感觉不是很清楚。NSURLConnection也可以设置执行代理的queue,通过setDelegateQueue:方法,本质上是NSURLConnection的机制需要创建此对象的线程的RunLoop去监听网络事件,然后执行注册的回调,所以在网络回来前,需要保持RunLoop的运行状态。NSURLSession应该是内部做了这个事情,所以发请求不需要所在线程“常驻”,而不是因为我们可以设置delegateQueue。从代理方法的调用栈看,NSURLSession的代理任务都是在com.apple.NSURLSession-work这个queue被塞进delegateQueue的,如果不设置delegateQueue的话,代理任务就在work队列执行,设置之后再派发到对应的队列。具体在work队列之前做了什么,还没看到比较具体的资料,不过基于底层都是CFNetworking,这个又是Source0,可能做的和常驻线程相似。
    2019-04-22
    6
    50
  • Tony
    多线程是有很多坑,但是多线程的好处以及如何正确使用多线程能讲讲吗?看完感觉没什么干货。
    2019-05-06
    1
    25
  • 唯她命
    老师你好,有个问题一直不理解,既然afn2.0讲所有的请求和回调 放在一个常驻线程里面,那么afn2.0的所有网络请求都在一个线程里了,那afn2.0岂不是单线程的吗?
    2019-04-18
    1
    10
收起评论
显示
设置
留言
32
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部