iOS多线程操作(NSThread,GCD,NSNSOperation )

来源:互联网 发布:淘宝发送优惠券给买家 编辑:程序博客网 时间:2024/06/06 02:37

1.一旦线程停止(死亡)了,就不能再次开启任务

2.NSThread的启动

1.显式启动:

1.创建,然后自己手动start [[NSThread alloc ] initWith...]

2.创建后 默认自动start [NSThreaddetachNewThreadSelector:....

2.隐式启动:

[selfperformSelectorInBackground:@selector..]

3.GCD  (可利用多核!)

有2个核心概念:

任务:执行什么操作

队列:用来存放任务  (将任务添加到队列中)

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

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


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

1.用同步的方式执行任务

dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

queue:队列

block:任务

2.用异步的方式执行任务

dispatch_async(dispatch_queue_t queue, dispatch_block_t block);


同步和异步的区别

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

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


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

1.并发队列(Concurrent Dispatch Queue

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

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

      2.串行队列(Serial Dispatch Queue

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

获得GCD队列:

1.并发队列

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

dispatch_queue_t xx = dispatch_get_global_queue("",0) //""的字符串是表示优先级的常量字符串

2.串行队列

1.使用dispatch_queue_create函数创建串行队列 

 注意非ARC需要释放手动创建的队列:dispatch_release(queue);


2.使用主队列跟主线程相关联的队列很常用, 用于线程间通讯--在子线程想回到主线程的时候用)

主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行

dispatch_queue_t queue =dispatch_get_main_queue();

放在主队列中的任务 必须是异步任务,不能是同步任务. 但是这时又很特殊,添加的异步任务不会开启线程,换句话说,异步任务 失去了 异步功能.

为什么放在主队列中的任务 同步任务不可以,异步任务可以?

首先,这是个主队列,必须在主线程里面执行,当将一个同步任务添加到主队列(串行)的时候,会放到队列的末尾,也就是等之前已经放入主队列的任务执行完才能执行,这个时候同步任务在等.但是问题是 同步任务必须在调用的时候 执行完才能继续向下执行,这个时候主队列的其他任务在等该同步任务,你等我,我等你 永远都再等.   但异步任务并不要求必须执行完才能继续向下执行,所以可以.

结论: 同步任务真的没有什么卵用.用的都是异步任务



4.NSOperation(每个对象只能被使用一次 使用第二次的时候 会坏指针)

1.NSInvocationOperation: 很没用,还不如使用GCD.只有在想要调用方法 而不是代码块的时候用.

1.创建出来后 直接start的话 是在主线程中执行

2.创建出来后,再创建一个队列(alloc init) 然后添加到队列中, 会自动异步开线程执行操作.

2.NSBlockOperation

1.若只封装一个操作,直接start的话 是在主线程中执行.   但是在start之前 还可以 [operation addExcutionBlock: ]增加操作.这些增加的操作开启子线程并发执行.

2.创建一个队列(alloc init) 然后添加到队列中,会全部自动异步开线程并发执行操作. 

3.若创建一个主队列 ,则在主线程里面执行.同样 如果其中一个op对象增加了操作.这些增加的操作开启子线程并发执行.

5.NSOperationQueue

基本用法:(下面介绍的是非主队列,并发执行操作)

1.添加NSOperation对象 [queue addOperation:]

2.直接 [queue addOperationWithBlock: ]  比GCD要简单一点 (其实差不多)

高级用法:

1.可以设置最大并发数(不包括主线程)queue.maxConCurrentOperationCount = 3;

当最大并发数为1的时候 其实这个队列就是串行队列!

2.依赖.[operation1 addDependency:]  这个用法完美解决 当时引出CCD的group的下载合并图片问题.

可以在不同queue的NSOperation之间创建依赖关系.

注意:不能相互依赖.

3.[operationA addCompletionBlock:]. 等operationA中的任务都执行完了 再执行completionBlock的代码. 

当operationA只有一个任务的时候 没什么卵用.但是当operationA有多个任务的时候 就有用了. 同样能解决 当时引出CCD的group的下载合并图片问题.

4.取消 cancelAllOperations 可以取消队列的所有操作(注意! 只能取消未开始的 已经开始的任务无法取消).  也可以调用操作的 cancel方法 取消当个操作.

5.暂停 setSuspended:(BOOL)b    YES代表暂停 NO代表恢复

6.从其他线程回到主线程的方式

1.perform...

[self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];

2.GCD

dispatch_async(dispatch_get_main_queue(), ^{

});

3.NSOperationQueue

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

     

}];



0 0
原创粉丝点击