美文网首页
关于iOS 多线程有关知识

关于iOS 多线程有关知识

作者: swordch | 来源:发表于2016-08-10 09:34 被阅读0次

多线程

GCD

1.任务和队列:

  任务:要做什么,一段代码,在GCD中就是Block,任务有同步执行sync和异步执行async,二者区别是是否开辟新线程.

     sync 阻塞当前进程并等待Block中任务执行完毕,然后线程才能继续执行下去

     async 当前线程会直接往下执行,不会阻塞当前线程

 队列:用于存放任务 串行队列和并行队列

串行队列:FIFO 一个一个先进后出执行

并行队列:并行队列中的任务也是FIFO取出来,不同的是,它取出来一个放到别的线程,然后再取出来一个又放到别的线程,由于取得动作快,看起来就是一起执行的,GCD会根据系统资源控制并行的数量,如果任务很多,不会让所有任务同时执行。

2.创建队列:

主队列:刷新UI,任何需要刷新UI的操作都在主队列进行,一般耗时的任务都放到别的线程执行

let queue = ispatch_get_main_queue()

自己创建的队列:第一个参数是标识符,用于DEBUG的时候标示唯一的队列,可以为空;第二个参数标示创建的队列是串行的还是并行的,nil或DISPATCH_QUEUE_SERAIL表示创建的是串行队列,参数DISPATCH_QUEUE_CONCURRENT表示创建的是并行队列

//串行队列

let queue = dispatch_queue_create("my.bourne.testqueue",nil)

let queue = dispatch_queue_create("my.bourne.testqueue",DISPATCH_QUEUE_SERIAL)

//并行队列

let queue = dispatch_queue_create("my.bourne.testqueue", DISPATCH_QUEUE_CONCURRENT)

全局并行队列:这是系统提供的一个并发队列

let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

3.创建任务

同步任务:会阻塞当前线程

dispatch_sync()

异步任务:不会阻塞当前线程

dispatch_async()

死锁:dispatch_sync 立即阻塞当前的主线程,然后把 Block 中的任务放到 main_queue 中,可是 main_queue 中的任务会被取出来放到主线程中执行,但主线程这个时候已经被阻塞了,所以 Block 中的任务就不能完成,它不完成,dispatch_sync 就会一直阻塞主线程,这就是死锁现象。导致主线程一直卡死。

NSOperation NSOperationQueue

    对GCD的封装,完全面向对象分别对应GCD中的任务和队列,执行的任务封装到一个NSOperation,再将任务添加到一个NSOperationQueue然后系统自动执行任务

NSOperation是一个抽象类,不能封装任务,它的两个子类可以封装任务,分别是NSInvocationOperation和NSBlockOpreation,前者是类型不安全,不建议使用

NSBlockOperation

let operationn = NSOperation({

in

//要执行代码。。。。

})

operation.start()

默认在当前线程执行,但是NSBlockOperation有个方法 addExecutionBlock通过这个方法可以给Operation 添加多个执行Block,block 会并发执行

主队列

多线程方案中都有一个主线程,这个特殊的线程必须串行,添加到主队列的任务都会一个接一个地排着队在主线程处理,通过单独的一个类方法来获得主队列

//

let queue = NSOperationQueue.mainQueue()

其他队列

通过初始化方法产生的队列就是其他队列了,因为只有这两种队列,除了主队列,其他队列就不需要名字了。其他队列的任务会在其他线程并行执行。

//创建其他队列

let queue = NSOperationQueue()

//创建NSBlockOperation对象

let operation = NSBlockOperation({

//.....执行的代码

})

queue.addOperation(operation)

    与GCD队列比较,这里没有串行队列,如果要实现多个任务在其他线程串行,可以使用NSOperationQueue的参数 maxConCurrentOperationCount最大并发数,用来设置最多可以让多少个任务同时执行,当设置为1时,就是串行了;NSOperationQueue还有一个添加任务的方法,addOperationWithBlock({block}),添加一个任务到队列中,十分方便。NSOperation还有一个实用功能,就是添加依赖,如有三个任务,A:从服务器下载一张图片;B:给这张图片加个水印,C:把图片返回给服务器,这时候就用到依赖了.

//任务一:下载图片

let operation1 = NSBlockOperation({

NSLog(“下载图片 - %@”,NSThread.currentThread)

NSThread.sleepForTimeInterval(1.0)

})

//任务二:打水印

let operation2 = NSBlockOperation({

NSLog(“打水印 - %@”,NSThread.currentThread)

NSThread.sleepForTimeInterval(1.0)

})

//任务三:上传图片

let operation3 = NSBlockOperation({

NSLog("上传图片 - %@",NSThread.currentThread)

NSThread.sleepForTimeInterval(1.0)

})

//4.设置依赖

operation2.addDependency(operation1)//任务二依赖任务一

operation3.addDependency(operation2)//任务三依赖任务二

//5.创建队列并加入任务

let queue = NSOperationQueue()

queue.addOperations([operation3, operation2, operation1],waitUntilFinished: false)

注意:1.不能添加相互依赖,会死锁

2.可以使用removeDependency来解除依赖关系

3.可以在不同的队列之间依赖,反正就是这个依赖是添加到任务身上的,和队列没有关系。

还有一些常用的方法:

NSOperation

BOOL executing:判断任务是否在正在执行

BooL finished 判断任务是否完成

void(^completionBlock)(void)用来设置完成后需要执行的操作

cancel 取消任务

waitUntilFinished()

NSOperationQueue

NSUInterger operationCount 队列的任务数

cancelAllOperations取消队列中的所有任务

waitUntilAllOperationsAreFinished 阻塞当前线程直到此队列中的所有任务执行完毕

queue setSuspended true 暂停队列

queue setSuspended false 继续

线程同步:

   所谓线程同步就是为了防止多个线程抢夺同一个资源造成的数据安全问题,所采取的一种措施,有很多实现方法。

1.互斥锁:给需要同步的代码块添加一个互斥锁,就可以保证每次只有一个线程访问此代码块

objc_sync_enter(self)

//需要执行的代码块

objc_sync_exit(self)

2.同步执行:我们可以使用多线程的知识,把多个线程都要执行此段代码添加到同一个串行队列,这样就实现了线程同步的概念,这里可以使用GCD和NSOperation

GCD:

//需要一个全局变量queue,要让所有线程的这个操作都加到一个queue中

dispatch_sync(queue,^{

NSInteger ticket = lastTicket;

[NSThread sleepForTimeInterval: 0.1];

NSLog(@"%ld - %@",ticket, [NSThread currentThread]);

ticket -= 1

lastTicket = ticket

})

//NSOperation& NSOperationQueue

//重点: 1,全局的NSOperationQueue 所有的操作添加到同一个queue 中

2.设置queue的maxConCurrentOperationCount 为1

3.如果后续操作需要Block中的结果,就需要调用每个操作的waitUntilFinished,阻塞当前线程

NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{

NSInteger ticket = lastTicket;

[NSThread sleepForTimeInteval:1];

NSLog(@"%ld - %@", [NSThread currentThread]);

ticket -= 1;

lastTicket = ticket;

}]

[queue addOperation: operatin];

[operation waitUntilFinished];

//后续要做的事情

延迟执行

延迟一段时间再试行某段代码

perform

//3秒后自动调用self的run:方法,并且传递参数:@“abc”

[self performSelector :@selector(run:) withObject:@"abc", afterDelay: 3];

GCD

GCD中的disatch_after方法。

//创建队列

dispatch_queue_t queue = diapatch_get_global_queue(DISPATCH_PRIORITY_DEFAULT, 0);

//设置延时,单位秒

double delay = 3;

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(delay* NESC_PER_SEC)), queue, ^{

//3秒后要执行的操作

})

NSTimer

[NSTimer scheduledTimerWithTimeInterval: 3.0 target: self selector:@selector(run:)]

单例模式

oc

@interface Tool:NSObject

+(instancetype) shareTool;

@end

@implementation Tool

static id_instance;

+(instancetype) shareTool {

static dispatch_once_t oneToken;

dispatch_once(&onceToken, ^{

_instance = [[Tool alloc] init];

})

return _instance;

}

@end

swift

class Tool: NSObject {

static let shareTool = Tool()

//私有化构造方法,阻止其他对象使用这个类的默认的“()”构造方法

private override init() {}

}

从其他线程回到主线程的方法

我们都知道在其他线程操作完成后必须要回到主线程更新UI,以下是一些方法回到主线程

NSThread

[self performSelectorOnMainThread:@selector(run) withObject: nil waitUnitilDone:NO];

GCD

//OC

dispatch_async(dispatch_get_main_queue, ^{

//....执行代码,刷新UI

})

//swift

dispatch_async(dispatch_get_main_queue, {

//执行刷新UI操作

})

NSOperationQueue

//oc

[[NSOperationQueue mainQueue] addOperationWithBlock:^ {

}];

//swift

NSOperationQueue.mianQueue().addOperationWithBlock{}

原文地址:http://www.jianshu.com/p/0b0d9b1f1f19

相关文章

  • 关于iOS 多线程有关知识

    多线程 GCD 1.任务和队列: 任务:要做什么,一段代码,在GCD中就是Block,任务有同步执行sync和异...

  • iOS 多线程知识相关

    前言 主要是整理下关于iOS中多线程的相关知识点,加强记忆 目前iOS有四种多线程 1.Pthreads2.NST...

  • iOS多线程的一些知识点

    讲述一些有关iOS中的多线程知识点,以及一些应用实例 一、多线程基础知识 多线程是一个比较轻量级的方法来实现单个应...

  • 轻松学iOS多线程之 GCD 的常用函数

    关于 iOS 多线程中 GCD 的基础知识已在上一篇文章中详细说明,请参看《轻松学iOS多线程之 GCD 的基本使...

  • iOS复习之多线程

    关于iOS多线程,你看我就够了iOS多线程--彻底学会多线程使用dispatch_group来进行线程同步 iOS...

  • OC--各种线程锁

    参考:正确使用多线程同步锁@synchronized()iOS中的锁iOS多线程安全详解iOS 常见知识点(三):...

  • 线程组管理页面多个并发请求

    最近看了本书。。。总结一下。。懒呐。。。又好久没写博客了。。。有关iOS多线程的基础知识可以看一下之前的文章iOS...

  • GeekBand - iOS 多线程和RunLoop 总结

    iOS 开发高级进阶 第三周 多线程 Runloop iOS 多线程以及 RunLoop 学习总结 基础知识 什么...

  • 多线知识点总结

    这篇是我看了下面的文章然后做的知识点整理,附上文章地址:关于iOS多线程,你看我就够了 多线程的技术种类 Pthr...

  • iOS 关于多线程(GCD)

    一、关于iOS多线程的一些简单操作 链接地址:多线程简介 二、iOS开发多线程篇—GCD的常见用法 主要为:延迟执...

网友评论

      本文标题:关于iOS 多线程有关知识

      本文链接:https://www.haomeiwen.com/subject/zmadsttx.html