iOS基础 - 多线程线程
一、多线程的应用
l 充分发挥多核处理器的优势,并发(同时执行)执行任务让系统运行的更快、更流畅
二、进程与线程概念
l 一个运行的程序就是一个进程或者叫做一个任务
l 一个进程至少包含一个线程,线程是程序的执行流
l iOS程序启动时,在创建一个进程的同时, 会开始运行一个线程,该线程被称为主线程
l 主线程是其他线程最终的父线程,所有界面的显示操作必须在主线程进行!!!
l 后台线程无法更新UI界面和响应用户点击事件
l 系统中的每一个进程都有自己独立的虚拟内存空间,而同一个进程中的多个线程则共用进程的内存空间
l 每创建一个新的线程,都会消耗一定内存和CPU时间
l 当多个线程对同一个资源出现争夺的时候需要注意线程安全问题
三、多线程的优势与难点
l 优势
- 充分发挥多核处理器优势,将不同线程任务分配给不同的处理器,真正进入“并行运算”状态
- 将耗时、轮询或者并发需求高等任务分配到其他线程执行,并由主线程负责统一更新界面会使得应用程序更加流畅,用户体验更好
- 当硬件处理器的数量增加,程序会运行更快,而无需做任何调整
l 难点
- 共享资源的“争夺”
- 多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了通过提高资源使用效率来提高系统的整体性能
四、多线程使用注意事项
l 线程使用不是无节制的
- iOS中的主线程的堆栈大小是1M
- 从第二个线程开始都是512KB
- 这些数值不能通过编译器开关或线程API函数更改
l 只有主线程有直接修改UI的能力
五、iOS的三种多线程技术
l NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程)
l 以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题
- NSOperation/NSOperationQueue 面向对象的线程技术
- GCD —— Grand Central Dispatch(派发) 是基于C语言的框架,可以充分利用多核,是苹果推荐使用的多线程技术
以上这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。但是就目前而言,iOS的开发者,需要了解三种多线程技术的基本使用过程。因为很多框架技术分别使用了不同多线程技术。
六、三种多线程技术的对比
l NSThread:
- 优点:NSThread 比其他两个轻量级,使用简单
- 缺点:需要自己管理线程的生命周期、线程同步、加锁、睡眠以及唤醒等。线程同步对数据的加锁会有一定的系统开销
l NSOperation:
- 不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上
- NSOperation是面向对象的
l GCD:
- Grand Central Dispatch是由苹果开发的一个多核编程的解决方案。iOS4.0+才能使用,是替代NSThread, NSOperation的高效和强大的技术
- GCD是基于C语言的
七、NSObject的多线程方法后台线程
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
通常,由于线程管理相对比较繁琐,而很多耗时的任务又无法知道其准确的完成时间,因此可以使用performSelectorInBackground方法直接新建一个后台线程,并将选择器指定的任务在后台线程执行,而无需关心具体的NSThread对象
- performSelectorInBackground方法本身是在主线程中执行的,而选择器指定的方法是在后台线程中进行的
- 使用performSelectorInBackground方法调用的任务可以更新UI界面
- 在大型交互式游戏中,通常使用此方法在后台线程播放音效
八、@autoreleasepool
l 内存管理对于多线程非常重要
l Objective-C可以凭借@autoreleasepool使用内存资源,并需要时回收资源
l 每个线程都需要有@autoreleasepool,否则可能会出现内存泄漏
九、NSObject的多线程方法主线程
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
如果要更新UI界面,可以在后台线程中调用performSelectorOnMainThread方法
尽管使用performSelectorInBackground方法调用的任务可以更新UI界面,但是在实际开发中,涉及到UI界面的更新操作,还是要使用performSelectorOnMainThread方法,以避免不必要的麻烦
十、NSThread
l 创建线程方法:
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
l 参数说明:
selector:线程执行的方法,只能有一个参数,不能有返回值
target:selector消息发送的对象
argument:传输给target的唯一参数,也可以是nil
十一、NSOperation & NSOperationQueue
l NSOperation的两个子类
NSInvocationOperation
NSBlockOperation
l 工作原理:
用NSOperation封装要执行的操作
将创建好的NSOperation对象放NSOperationQueue中
启动OperationQueue开始新的线程执行队列中的操作
l 注意事项:
使用多线程时通常需要控制线程的并发数,因为线程会消耗系统资源,同时运行的线程过多,系统会变慢
使用以下方法可以控制并发的线程数量:
(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
十二、GCD
l GCD是基于C语言的框架
l 工作原理:
让程序平行排队的特定任务,根据可用的处理资源,安排它们在任何可用的处理器上执行任务
要执行的任务可以是一个函数或者一个block
底层是通过线程实现的,不过程序员可以不必关注实现的细节
GCD中的FIFO队列称为dispatch queue,可以保证先进来的任务先得到执行
dispatch_notify 可以实现监听一组任务是否完成,完成后得到通知
l GCD队列:
全局队列:所有添加到主队列中的任务都是并发执行的
串行队列:所有添加到串行队列中的任务都是顺序执行的
主队列:所有添加到主队列中的任务都是在主线程中执行的
十三、获取队列的方法
l 全局队列(可能会开启多条线程)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
l 串行队列(只可能会开启一条线程)
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
l 主队列
dispatch_get_main_queue();
十四、GCD任务的执行方式同步&异步
l 异步操作
dispatch_async 在其他线程执行任务,会开启新的线程
异步方法无法确定任务的执行顺序
l 同步操作
dispatch_sync 在当前在当前线程执行任务,不开启新的线程
同步操作与队列无关
同步方法会依次执行,能够决定任务的执行顺序
更新界面UI时,最好使用同步方法
十五、GCD的优点
l 充分利用多核
l 所有的多线程代码集中在一起,便于维护
l GCD中无需使用@autoreleasepool
l 如果要顺序执行,可以使用dispatch_sync同步方法
l dispatch_async无法确定任务的执行顺序
十六、单例模型
l 目的:
保证在内存中永远只有类的单个实例
l 建立方法:
声明一个静态成员变量,记录唯一实例
重写allocWithZone方法
allocWithZone方法是对象分配内存空间时,最终会调用的方法,重写该方法,保证只会分配一个内存空间
建立sharedXXX类方法,便于其他类访问
互斥锁的目的,一次只让一个线程访问资源,从而达到资源的线程安全。
iOS基础 - 多线程线程的更多相关文章
- Java基础-多线程-③线程同步之synchronized
使用线程同步解决多线程安全问题 上一篇 Java基础-多线程-②多线程的安全问题 中我们说到多线程可能引发的安全问题,原因在于多个线程共享了数据,且一个线程在操作(多为写操作)数据的过程中,另一个线程 ...
- Java基础-多线程-①线程的创建和启动
简单阐释进程和线程 对于进程最直观的感受应该就是“windows任务管理器”中的进程管理: (计算机原理课上的记忆已经快要模糊了,简单理解一下):一个进程就是一个“执行中的程序”,是程序在计算机上的一 ...
- java基础-多线程线程池
线程池 * 程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互.而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池.线程池里的每一个线程代 ...
- iOS开发多线程-线程间通讯
一.NSThread 线程间的通讯 - (void)demoAboutNSThread { NSLog(@"demoAboutNSThread %@", [NSThread cur ...
- java基础-多线程-线程组
线程组 * Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制. * 默认情况下,所有的线程都属于主线程组. * public fi ...
- Java基础-多线程-②多线程安全问题
什么是线程的安全问题? 上一篇 Java基础-多线程-①线程的创建和启动 我们说使用实现Runnable接口的方式来创建线程,可以实现多个线程共享资源: class Dog implements Ru ...
- iOS开发多线程篇—线程安全
iOS开发多线程篇—线程安全 一.多线程的安全隐患 资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块 ...
- iOS开发多线程篇—创建线程
iOS开发多线程篇—创建线程 一.创建和启动线程简单说明 一个NSThread对象就代表一条线程 创建.启动线程 (1) NSThread *thread = [[NSThread alloc] in ...
- iOS开发多线程篇—线程间的通信
iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任 ...
随机推荐
- linux安装和配置 mysql、redis 过程中遇到的问题记录(转)
章节目录 mysql redis linux下部署mysql和redis网上的教程很多,这里记录一下我部署.配置的过程中遇到的一些问题和解决办法. mysql ①安装完成后启动的时候报错 Starti ...
- N-gram统计语言模型(总结)
N-gram统计语言模型 1.统计语言模型 自然语言从它产生開始,逐渐演变成一种上下文相关的信息表达和传递的方式.因此让计算机处理自然语言.一个主要的问题就是为自然语言这样的上下文相关特性建立数学模型 ...
- 编程算法 - 阅读完整的文件(C++)
阅读完整的文件(C++) 本文地址: http://blog.csdn.net/caroline_wendy C++: 把文本文件(txt)的全部内容读入字符串(string), 最高效的方法. 代码 ...
- React.js再探(二)
上文中说到了组件了. 我们使用组件的目的最大莫过于复用,提供生产效率. 那么,这时候组件就应该能够提供一些”api”出来,让开发者去定义在不同场景下的不同表现,比如,行为或外观等. 而这些“api”就 ...
- 【百度地图API】如何制作班级地理通讯录?LBS通讯录
原文:[百度地图API]如何制作班级地理通讯录?LBS通讯录 摘要:班级通讯录必备的功能,比如人员列表,人员地理位置标注,展示复杂信息窗口,公交和驾车等.一般班级人员都不会超过300个,因为可以高效地 ...
- [VirtualBox] - Install Oracle Linux 7 on Oracle VirtualBox
I'll start coding with JEE soon. Product environment adopts Oracle + WebLogic in Linux, technology a ...
- 关于tasklet的一点小小的解释
大概有一些同学对tasklet的串行化还有点困惑,其实在单处理器上最好理解,所以本帖主要讨论多处理器上tasklet如何实现串行化:同一个tasklet对象同一时刻只能在一个处理器上运行. 在 驱动程 ...
- lcc之内存分配
现在感觉这本书有些地方没有说透,如果自己的理解能力与基础知识够强的话,理解起来还好,如果不行的话,某些地方理解起来会相当的头疼. 现在来说说内存管理.当初看这一章的时候很快就过去了,感觉很多地方很好理 ...
- Facebook Hack 语言 简介
1. Hack 是什么? Hack 是一种基于HHVM(HipHop VM 是Facebook推出的用来执行PHP代码的虚拟机,它是一个PHP的JIT编译器,同时具有产生快速代码和即时编译的优点.)的 ...
- 从用python做zoj1011发生Non-zero Exit Code错误说起
近期做了浙大oj的第1011道题,遇见一件奇怪的事.这道题我用c++和php做,提交后都正确.可是用全然同样的逻辑改写成python代码提交后却产生了Non-zero Exit Code的判题结果.p ...