swift编程开发iOS开发iOS学习笔记

iOS中的多线程篇--之一

2016-09-05  本文已影响114人  stoneZ

一、进程和线程的概念与本质以及优缺点

1、进程: 进程指的是系统中运行的一个应用程序,系统中的每个进程都是相互独立的,各自运行在其专用的并且受到保护的内存空间中。

2、线程: 进程中药完成一些任务,而这些任务就是交给线程来管理的,一个进程中至少有一条线程(主线程),也可以有多条线程(子线程),进程中的任何任务都是在线程中执行的。

3、线程的串行:线程中任务的执行是串行的,如果想在线程中执行多个任务,那么只能一个一个按顺序执行,也就是说,子啊同一时刻,线程只能处理一个任务

4、多线程:一个进程中可以开启多条线程,每条线程可以同时执行任务,从而提高了程序的运行效率(优点之一)

5、多线程的原理:其实,在同一时刻,CPU只能处理一条线程,也就是只能执行一条任务,多线程的并发执行,其实是CPU快速的在多个线程之间调度 (切换),因此,如果进程中的线程数太多,会大量消耗cpu资源,线程的切换执行的频次会降低,从而线程的执行效率会大大降低

6、多线程的优点:a. 能够适当的提高程序的执行效率,,提高资源的利用率(CPU、内存的利用率)

缺点:    b. 创建线程是有开销的,ios下的开销主要包括栈空间的内存消耗(子线程512KB,主线程1MB,也可以使用-setStackSize来设置线程所占栈空间的大小,但是必须是4K的倍数,而且最小的是16K),创建线程大约需要90毫秒的时间,搜易如果开启大量线程,会降低程序的执行效率, 并且CPU在调度线程上的开销会增大,因为涉及到线程之间的通信 和数据共享问题,所以会增加程序的设计复杂度

二、 IOS中的多线程

1、ios中的主线程: IOS运行一个程序时,会默认开启一条线程,称为“主线程”或者也可以叫做“UI线程”,这条线程的主要任务如下 :        a.  显示或者刷新UI

b. 处理UI事件(用户的点击拖拽等事件)

因此,为了有良好的用户交互体验,千万不能将耗时操作放大主线程中来;

2、IOS中实现多线程的方案:

a. pthread            c语言      生命周期程序员管理

b. NSThread        OC语言  生命周期程序员管理

c. GCD c语言 自行管理生命周期

d. NSOperation oc语言    自行管理生命周期

三、NSThread的使用

1、创建线程方式一:

NSThread* thread = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];

[thread start];  //手动开启此线程

创建线程方式二:

[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

创建线程的方式三:

[self performSelectorInBackground:@selector(run) withObject:nil];

方式二和方式三开启线程优点:方便快捷

缺点:无法对线程进行详细的设置

2、安全隐患:存在多条线程抢夺同意资源的问题

解决办法:使用互斥锁    格式: @synchronized(锁对象) {//需要锁定的代码}

3、线程之间的通讯实例之一:

-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait

四 GCD的使用:

GCD中有2个核心概念

任务:执行什么操作

队列:用来存放任务

将任务添加到队列中,GCD会自动将队列中的任务取出,放到对应的线程中执行

任务的取出遵循队列的FIFO原则:先进先出,后进后出

GCD中有2个用来执行任务的函数

用同步的方式执行任务

dispatch_sync (dispatch_queue_t queue, dispatch_block_t block);

queue:队列

block:任务

用异步的方式执行任务    dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

同步和异步的区别

同步:只能在当前线程中执行任务,不具备开启新线程的能力

异步:可以在新的线程中执行任务,具备开启新线程的能力

GCD的队列可以分为2大类型

并发队列(Concurrent Dispatch Queue)

可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)

并发功能只有在异步(dispatch_async)函数下才有效

串行队列(Serial Dispatch Queue)

让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)

有4个术语比较容易混淆:同步、异步、并发、串行

同步和异步主要影响:能不能开启新的线程

同步:在当前线程中执行任务,不具备开启新线程的能力

异步:在新的线程中执行任务,具备开启新线程的能力

并发和串行主要影响:任务的执行方式

并发:多个任务并发(同时)执行

串行:一个任务执行完毕后,再执行下一个任务

GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建

使用dispatch_get_global_queue函数获得全局的并发队列

dispatch_queue_t dispatch_get_global_queue(

dispatch_queue_priority_t priority, // 队列的优先级

unsigned long flags); // 此参数暂时无用,用0即可

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 获得全局并发队列

线程之间的通讯:

从子线程回到主线程

dispatch_async(

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

// 执行耗时的异步操作...

dispatch_async(dispatch_get_main_queue(), ^{

// 回到主线程,执行UI刷新操作

});});

其他用法:

iOS常见的延时执行有2种方式

调用NSObject的方法

[self performSelector:@selector(run) withObject:nil afterDelay:2.0];

// 2秒后再调用self的run方法

使用GCD函数

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

// 2秒后异步执行这里的代码...

});

单例模式:

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

// 只执行1次的代码(这里面默认是线程安全的)

});

需求:

首先:分别异步执行2个耗时的操作

其次:等2个异步操作都执行完毕后,再回到主线程执行操作

如果想要快速高效地实现上述需求,可以考虑用队列组

dispatch_group_t group =  dispatch_group_create();

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

// 执行1个耗时的异步操作

});

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

// 执行1个耗时的异步操作

});

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

// 等前面的异步操作都执行完毕后,回到主线程...

});

上一篇 下一篇

猜你喜欢

热点阅读