iOS开发中实现多线程的方式主要包括以下一个方面,我们会通过后续的文章一一介绍他们
pthread: 跨平台**,适用于多种操作系统,可移植性强,是一套纯C语言的通用API,且线程的生命周期需要程序员自己管理,使用难度较大,所以在实际开发中通常不使用。
NSThread: 基于OC语言的API,使得其简单易用,面向对象操作。线程的声明周期由程序员管理,在实际开发中偶尔使用,底层实现是基于pthread。
GCD: 基于C语言的API,充分利用设备的多核,旨在替换NSThread等线程技术。线程的生命周期由系统自动管理,在实际开发中经常使用。
NSOperation: 基于OC语言API,底层是GCD,增加了一些更加简单易用的功能,使用更加面向对象。线程生命周期由系统自动管理,在实际开发中经常使用。
本文详细介绍了pthread和NSThread在iOS中的使用,主要包括以下几个方面
- pthread
- pthread 简介
- pthread 使用方法
- pthread 其他相关方法
- NSThread
- 创建、启动线程
- NSThread常用方法
- NSThread状态控制
- NSThread线程间的通信
pthread 简介
pthread 是一套通用的多线程的 API,可以在Unix / Linux / Windows 等系统跨平台使用,使用 C 语言编写,需要程序员自己管理线程的生命周期,使用难度较大,我们在 iOS 开发中几乎不使用直接 pthread,但是还是来可以了解一下的。
引自 百度百科
POSIX 线程(POSIX threads),简称 Pthreads,是线程的 POSIX 标准。该标准定义了创建和操纵线程的一整套 API。在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用 Pthreads 作为操作系统的线程。Windows 操作系统也有其移植版 pthreads-win32。引自 维基百科
POSIX 线程(英语:POSIX Threads,常被缩写 为 Pthreads)是 POSIX 的线程标准,定义了创建和操纵线程的一套 API。
实现 POSIX 线程标准的库常被称作 Pthreads,一般用于 Unix-like POSIX 系统,如 Linux、Solaris。但是 Microsoft Windows 上的实现也存在,例如直接使用 Windows API 实现的第三方库 pthreads-w32;而利用 Windows 的 SFU/SUA 子系统,则可以使用微软提供的一部分原生 POSIX API。
pthread 使用方法
- 首先要包含头文件
#import <pthread.h>
- 其次要创建线程,并开启线程执行任务
1 | // 1. 创建线程: 定义一个pthread_t类型变量 |
pthread_create(&thread, NULL, run, NULL);
中各项参数含义:- 第一个参数
&thread
是线程对象,指向线程标识符的指针 - 第二个是线程属性,可赋值
NULL
- 第三个
run
表示指向函数的指针(run对应函数里是需要在新线程中执行的任务) - 第四个是运行函数的参数,可赋值
NULL
pthread 其他相关方法
pthread_create()
创建一个线程pthread_exit()
终止当前线程pthread_cancel()
中断另外一个线程的运行pthread_join()
阻塞当前的线程,直到另外一个线程运行结束pthread_attr_init()
初始化线程的属性pthread_attr_setdetachstate()
设置脱离状态的属性(决定这个线程在终止时是否可以被结合)pthread_attr_getdetachstate()
获取脱离状态的属性pthread_attr_destroy()
删除线程的属性pthread_kill()
向线程发送一个信号
NSThread
NSThread 是苹果官方提供的,使用起来比 pthread 更加面向对象,简单易用,可以直接操作线程对象。不过也需要需要程序员自己管理线程的生命周期(主要是创建),我们在开发的过程中偶尔使用 NSThread。比如我们会经常调用[NSThread currentThread]
来显示当前的进程信息。
下边我们说说 NSThread 如何使用。
创建、启动线程
- 先创建线程,再启动线程
1 | // 1. 创建线程 |
- 创建线程后自动启动线程
1 | // 1. 创建线程后自动启动线程 |
- 隐式创建并启动线程
1 | // 1. 隐式创建并启动线程 |
线程相关用法
1 | // 获得主线程 |
线程状态控制方法
- 启动线程方法
1 | - (void)start; |
- 阻塞(暂停)线!程方法
1 | + (void)sleepUntilDate:(NSDate *)date; |
- 强制停止线程
1 | + (void)exit; |
线程之间的通信
在开发中,我们经常会在子线程进行耗时操作,操作结束后再回到主线程去刷新 UI。这就涉及到了子线程和主线程之间的通信。我们先来了解一下官方关于 NSThread 的线程间通信的方法。
1 | // 在主线程上执行操作 |
下面通过一个经典的下载图片 DEMO 来展示线程之间的通信。具体步骤如下:
- 开启一个子线程,在子线程中下载图片。
- 回到主线程刷新 UI,将图片展示在 UIImageView 中。
DEMO 代码如下:
1 | /** |
所有多线程方式都涉及的安全同步的问题,后续会专门写一篇文章来补充这方面知识