iOS多线程系列一

概述

本文主要讲解iOS线程相关的知识,对于一个iOS开发者,如果想保证自己所开发的应用流畅的运行,线程的知识是无法绕开的。通过阅读本文,你讲了解到如下知识:

  • 进程和线程
  • 线程的生命周期
  • NSThread基本用法
  • 线程间的通信

进程和线程的

进程

用最通俗的话来解释进程:启动一个app,就是开启了一个进程。当你使用某款App,一边浏览它所提供的内容,一边使用它下载图片,这需要用多个线程来完成上述操作。

进程是应用的一次执行,线程是CPU的最小执行单元,一个进程里可以包含多个线程。

线程的生命周期

线程的生命周期
对于一个线程而言,它经历了新建就绪运行阻塞死亡 这几个阶段。解释如下:

新建: 线程刚被创建,还没有被调用。

就绪: 调用了线程的start的方法之后,线程就进入就绪状态。

运行: 当CPU从就绪队列中调用到该线程,该线程进入运行状态。

死亡: 当线程执行完毕或者线程被强制退出,线程就进入死亡状态。

阻塞: 当正在运行的线程被其他其他优先级更高的线程抢断或者调用线程的sleep方法,线程就进入了阻塞状态,当sleep结束,线程进入就绪状态,等待CPU的调度。

这是线程的最基本生命周期,iOS中与线程生命周期相关的有一个非常重要的东西就是:runloop。 本文暂不涉及这方面的知识,以后再讲解。

接下来我们讲解iOS多线程相关的API,第一个就是NSThread。

NSThread的基本用法

NSThread是对C语言中的线程管理相关代码的封装。用来提供面向对象的线程管理方法。

创建:

1
2
//第一种方法
self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadAction) object:nil];

这种方法会在线程执行的时候调用threadAction这个回调方法,你需要将自己的任务写在这个方法中。

1
2
3
4
5
//第二种方法
self.thread = [[NSThread alloc] initWithBlock:^{
NSLog(@"%@", [NSThread currentThread]);
[self task];
}];

这种方法会在线程执行的时候调用block里的任务,你需要将自己的任务写在block中。

开启:

1
[self.thread start];

取消:

1
[self.thread cancel];

休眠

1
[NSThread sleepForTimeInterval:3];

获取当前线程

1
[NSThread currentThread];

获取线程状态

1
2
3
4
5
6
7
8
//当前线程是不是主线程
self.thread.isMainThread
//当前线程是不是正在执行
self.thread.isExecuting
//当前线程是不是执行完毕了
self.thread.isFinished
//当前app是不是一个多线程app, 对于iOS而已,肯定是的,返回YES
self.thread.isMultiThreaded

注意: 对于一个已经finished的线程,不能再调用其start方法了,会崩溃。

线程间的通信

在iOS中,UI相关的操作需要回到主线程进行操作,那么如何在NSThread线程中回到主线程呢?

1
2
3
4
5
//回到主线程执行
[self performSelectorOnMainThread:@selector(onMainThreadWork) withObject:nil waitUntilDone:NO];
//回到指定的线程执行
[self performSelector:@selector(方法名) onThread:执行的线程 withObject:参数 waitUntilDone:是否阻塞];

waitUntilDone这个参数表示是否阻塞当前代码,yes表示阻塞,selecotor方法不执行完毕,则代码一直阻塞在这里,不往下执行。no表示不阻塞,即不等待selector方法执行完毕。·

其他

本文首发于RiverLi的个人公众号,如需转载请与我本人联系。
由于本博客暂未开放评论功能,如有任何问题,请关注我的公众号(RiverLi),给我留言,或者在对应的文章评论。
RiverLi的公众号