在OC中多线程管理包含GCD、NSThread、NSOperationQueue。

下面简单介绍。

进程和线程

进程:正在进行中的程序叫做进程,负责程序运行的内存分配。

每一个进程都有自己独立的虚拟内存空间。

线程:线程是进程中一个特立的执行路径(控制单元)

一个进程至少包含一条线程,即主线程,开发中通常把比较耗时的线程(如:网络请求)放在子线程中执行。

创建线程的目的:开启一条新的执行路径,运行指定的代码,与主线程的代码能够实现同时执行。

一、GCD

GCD:Grand Central Dispatch

GCD里包含了串行队列、并行队列、主队列、全局队列。

串行队列:可以创建任意个数的串行队列,每个队列依次执行顺序执行。一个队列同一时刻只能执行一个任务,下一个任务的执行依赖于上一任务的完成,但是各个队列之间不影响,可以并发执行。一个队列的任务运行在一个线程上,一个队列只有一个线程。

串行队列的同步任务和异步任务:dispatch_sync和dispatch_async

串行同步执行结果:不会创建新线程,按照顺序执行。

串行异步执行结果:创建一个新线程,依旧顺序执行。(常用)

串行先执行异步,再执行同步:发现同步一直是在主线程,但是先让异步的执行完再来执行同步的。

一个串行队列是顺序执行的,不影响主线程的操作。

在串行队列中,不能嵌套多一个同步任务。会造成阻塞。

并行队列:并行队列不允许自己创建,系统中存在三个不同优先级的并行队列。并行队列依旧按照任务的添加的顺序启动任务,但是,后一个任务无需等待前一个任务执行完才开始执行,而是启动前一个任务后,立即启动下一个任务。至于同一时刻允许同时运行多少个任务由系统决定。

任务各自运行在并行队列为他们提供的独立线程上,并行队列中同时运行多少个任务,就必须维护多少个线程。

并行队列的同步和异步任务:dispatch_sync和dispatch_async

并行同步执行结果:不会创建新线程,按照顺序执行。(不同串行同步)

并行异步执行结果:会新建多个线程,任务无序执行。

并行先执行同步,再执行异步的结果:发现同步执行完才会执行异步。

并行先执行异步,再执行同步的结果:执行顺序完全乱作一团。

主队列:主队列的任务运行在主线程上,所以,如果你要修改应用程序的界面,它是唯一的选择。

主队列中添加的同步操作永远不会被执行,会死锁。

全局队列:为了方便多线程的使用,供所有APP共同使用。

全局队列先执行同步,再执行异步的结果:先同步再异步。

小结一下:

串行队列,同步任务,不需要新建线程。

串行队列,异步任务,需要一个子线程,线程的创建和回收不需要程序猿参与。

并行队列,同步任务,不需要创建线程。

并行队列,异步任务,有多少个任务,就开多少个线程执行。

无论是什么队列和什么任务,线程的创建和回收都不需要程序猿的参与。

线程的创建回收工作由队列负责。


NSThread

优点:比GCD,NSOperationQueue较轻量级。

缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销。

一、获取当前线程

NSThread *current = [NSThread currentThread];

二、获取主线程

1 NSThread *main = [NSThread mainThread];
2 NSLog(@"主线程:%@", main);

  打印结果是:

2013-04-18 21:36:38.599 thread[7499:c07] 主线程:<NSThread: 0x71434e0>{name = (null), num = 1}

三、NSThread的创建。

1、动态方法

- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;

 使用例子:

 在第二行创建一条新线程,然后再第四行调用start方法启动线程,线程启动会调用self的run:方法,并且将@”shaoting“作为方法参数。

1 // 初始化线程
2 NSThread *thread = [[[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"shaoting"] autorelease];
3 // 开启线程
4 [thread start];

 例如run:方法是这样的:

1 - (void)run:(NSString *)string {
2 NSThread *current = [NSThread currentThread];
3 NSLog(@"执行了run:方法-参数:%@,当前线程:%@", string, current);
4 }

  打印结果为:

2013-04-18 21:40:33.102 thread[7542:3e13] 执行了run:方法-参数:mj,当前线程:<NSThread: 0x889e8d0>{name = (null), num = 3}

  可以看出,这条线程的num值为3,说明不是主线程。

2、静态方法

+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument; 
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"shaoting"];

  执行完上面代码后马上启动一条新线程,并且这条线程调用self的run方法,以@“shaoting”为方法参数。

3、隐式创建线程

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

 会隐式的创建一条新线程,并且在这条线程上调用self的run方法,以@“shaoting”为方法参数。

4、暂停当前线程

[NSThread sleepForTimeInterval:2];
NSDate *date = [NSDate dateWithTimeInterval:2 sinceDate:[NSDate date]];
[NSThread sleepUntilDate:date];

  上面两种做法都是暂停当前线程2秒。

5、线程的其他操作

在指定线程上执行操作

1 [self performSelector:@selector(run) onThread:thread withObject:nil waitUntilDone:YES];

  在thread这条线程上调用self的run方法。

最后的YES代表:上面得代码会造成阻塞,等run方法在thread线程执行完毕后,上面的代码才会通过。

在主线程上执行操作

[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES];

在主线程调用self的run方法。

在当前线程执行操作

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

在当前线程调用self的run方法。

 


 NSOperationQueue

一个NSOperation对象可以通过调用start方法来执行任务,默认是同步执行的。也可以将NSOperation添加到一个NSOperationQueue中去执行,而且是异步执行的。

1、创建一个操作队列:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

2、添加NSOperation到NSOperationQueue中

  添加一个operation

[queue addOperation:operation];

  添加一组operation

[queue addOperations:operations waitUntilFinished:NO];

  添加一个block形式的operation

[queue addOperationWithBlock:^() {
NSLog(@"执行一个新的操作,线程:%@", [NSThread currentThread]);
}];

3、添加NSOperation的依赖对象

当某个NSOperation对象依赖于其他NSOperation对象的完成时,就可以通过addDependency方法添加一个或者多个依赖的对象,只有所有依赖的对象都已经完成操作,当前NSOperation才开始执行操作。通过removeDependency方法来删除依赖对象。

[operation2 addDependency:operation1];

  添加依赖,不局限于必须在同一个queue中的NSOperation对象,可以完全在不同queue之间的NSOperation对象创建依赖关系。但是不能创建互相依赖关系的依赖。

4、设置队列的最大并发操作数量。

队列的最大并发操作数量,意思是队列最多同时运行几条线程。

// 每次只能执行一个操作
queue.maxConcurrentOperationCount = 1;
// 或者这样写
[queue setMaxConcurrentOperationCount:1];

5、等待options完成

// 会阻塞当前线程,等到某个operation执行完毕
[operation waitUntilFinished];

  

// 阻塞当前线程,等待queue的所有操作执行完毕
[queue waitUntilAllOperationsAreFinished];

6、暂停和继续queue

  

// 暂停queue
[queue setSuspended:YES]; // 继续queue
[queue setSuspended:NO];

  

 

OC多线程管理的更多相关文章

  1. OC内存管理 @property的增强

    涉及到内存管理,只读,多线程等很多功能时,setter和getter方法也就没那么简单了:当然@property依然强大,很好用: 1:内存管理相关参数: *:retain:  (如果是oc对象类型) ...

  2. 浅谈OC内存管理

    一.基本原理 (一)为什么要进行内存管理. 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,这时需要回收一些不需要再继续使用的内存空 ...

  3. OC内存管理-OC笔记

    内存管理细节:http://blog.sina.com.cn/s/blog_814ecfa90102vus2.html 学习目标 1.[理解]内存管理 2.[掌握]第一个MRC程序 3.[掌握]内存管 ...

  4. OC 内存管理之手动内存管理MRC

    一.基本原理 1.什么是内存管理 内存管理的重要性: 移动设备的内存极其有限,每个app所能占用的内存是有限制的 当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间. ...

  5. OC内存管理总结,清晰明了!

    <span style="font-size:18px;">OC内存管理 一.基本原理 (一)为什么要进行内存管理. 由于移动设备的内存极其有限.所以每一个APP所占的 ...

  6. OC 内存管理机制总结

    OC 内存管理机制总结 一:OC内存管理机制目前分为两块,其一自动内存管理机制,其二手动内存管理机制: 1.首先我们从自动内存管理机制讲起: 1)什么是自动内存管理机制,自动内存管理机制就是程序中所创 ...

  7. OC内存管理基础

    OC 内存管理基础 一. retain和release基本使用 使用注意: 1.你想使用(占用)某个对象,就应该让对象的计数器+1(让对象做一次retain操作) 2.你不想再使用(占用)某个对象,就 ...

  8. QF——OC内存管理详解

    堆的内存管理: 我们所说的内存管理,其实就是堆的内存管理.因为栈的内存会自动回收,堆的内存需要我们手动回收. 栈中一般存储的是基本数据类型变量和指向对象的指针(对象的引用),而真实的对象存储在堆中.因 ...

  9. OC内存管理-黄金法则

    1.内存管理-黄金法则 The basic rule to apply is everything that increases the reference counter with alloc, [ ...

随机推荐

  1. Hibernate4+Spring JPA+SpringMVC+Volecity搭建web应用(二)

    SpringMVC.xml配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&qu ...

  2. hdu----(5055)Bob and math problem(贪心)

    Bob and math problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  3. ARM流水线关键技术分析与代码优化

    引 言    流水线技术通 过多个功能部件并行工作来缩短程序执行时间,提高处理器核的效率和吞吐率,从而成为微处理器设计中最为重要的技术之一.ARM7处理器核使用了典型三级流 水线的冯·诺伊曼结构,AR ...

  4. (转载整理)SAP ERP常用T-CODE

    其实最讨厌做ERP的项目了.不过,身不由己的嘛! 网上资料加一些整理. 与客户相关  VD01 建立客户 Create customerVD02 更改客户 Change customerVD03 显示 ...

  5. BroadcastReceiver的实例----基于Service的音乐播放器之一

    下面的程序开发了一个基于Service的音乐盒,程序的音乐将会由后台运行的Service组件负责播放,当后台的播放状态发生改变时,程序将会通过发送广播通知前台Activity更新界面:当用户单击前台A ...

  6. HBase HMaster Architecture - HBase Master架构

    HBase architecture follows the traditional master slave model where you have a master which takes de ...

  7. iOS https(SSL/TLS)数据捕获

    要捕获iPhone上的appstore的数据还真的没那么容易,以前介绍的那些使用代理手工导入证书的方法已经完全失效了,结果就是安装证书之后再打开appstore也无法正常的建立连接.按照我的分析其实是 ...

  8. DataGridView绑定数据库,取得的数据插入到DataGridView指定列(一)

    实现: 点击button1,从数据库中获得数据,指定数据库的某列数据插入到DataGridView指定列 一.双击button1进入事件代码 private void button1_Click(ob ...

  9. WebBrowers & HtmlViewers collection

    WebBrowers & HtmlViewers collection 浏览: 加入我的收藏 楼主: THtmlViewerhttps://github.com/BerndGabriel/Ht ...

  10. ios 常用的小框架

    在ios开发中,一些请求 kvc 下拉列表  图片请求等等自己手写代码的话非常麻烦,还容易出现一系列的问题,现在整理了一些常用的一些小框架. 其中MJExtension 和 MJRefresh 这两个 ...