iOS多线程入门之NSThread,NSOperation,GCD

转载 2015年07月08日 18:42:19

一 线程的概念


一个运行着的程序就是一个进程或者叫做一个任务,一个进程至少包含一个线程,线程就是程序的执行流。Mac和iOS中的程序启动,创建好一个进程的同时, 一个线程便开始运行,这个线程叫主线程。主线程在程序中的地位和其他线程不同,它是其他线程最终的父线程,且所有界面的显示操作即AppKit或 UIKit的操作必须在主线程进行。 

系统中的每一个进程都有自己独立的虚拟内存空间,而同一个进程中的多个线程则共用进程的内存空间。每创建一个新的线程,都需要一些内存(如每个线程有自己的Stack空间)和消耗一定的CPU时间。另外当多个线程对同一个资源出现争夺的时候需要注意线程安全问题。

二 iOS的三种多线程技术特点:

1.NSThread:

    1> 优点:NSThread对象建立一个线程非常方便;

    2> 缺点:要使用NSThread管理多个线程非常困难,不推荐使用;

    3> 技巧:使用[NSThread currentThread]跟踪任务所在线程,适用于这三种技术.

2.NSOperation/NSOperationQueue:

    1> 概念1:是使用GCD实现的一套Objective-C的API;

    2> 概念2是面向对象的多线程技术;

    3> 优点:提供了一些在GCD中不容易实现的特性,如:限制最大并发数量,操作之间的依赖关系.

3.GCD---Grand Central Dispatch:

    1> 概念:是基于C语言的底层API;

    2> 优点1:用Block定义任务,使用起来非常灵活便捷;

    3> 优点2:提供了更多的控制能力以及操作队列中所不能使用的底层函数.



三  NSThread

1、线程创建与启动

线程创建主要有二种方式:

  1. - (id)init; // designated initializer  
  2. - (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument; 

当然,还有一种比较特殊,就是使用所谓的convenient method,这个方法可以直接生成一个线程并启动它,而且无需为线程的清理负责。这个方法的接口是:

  1. + (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument 

前两种方法创建后,需要手机启动,启动的方法是:

  1. - (void)start; 

eg: 

[objc] view plaincopy
  1. 1.1:[NSThread detachNewThreadSelector:@selector(threadInMainMethod:) toTarget:self withObject:nil];  
  2.    
  3. 1.2:NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(threadInMainMethod:) object:nil];  
  4.  [myThread start];   
  5. 1.3:  [obj performSelectorInBackground:@selector(threadMe) withObject:nil];</span>  


四 NSOperation/NSOperationQueue

使用 NSOperation的方式有两种,

一种是用定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。

另一种是继承NSOperation


创建方法

  1. NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self  
  2.                                                                            selector:@selector(downloadImage:)  
  3.                                                                              object:kURL];  
  4.       
  5.     NSOperationQueue *queue = [[NSOperationQueue alloc]init];  
  6.     [queue addOperation:operation];  

一个NSOperationQueue 操作队列,就相当于一个线程管理器,而非一个线程。因为你可以设置这个线程管理器内可以并行运行的的线程数量等等。

[objc] view plaincopy
  1. [queue setMaxConcurrentOperationCount:1];   

添加和删除NSOperation的依赖对象addDependency与removeDependency方法

设置优先级:setQueuePriority:

设置队列的最大并发数:maxConcurrentOperationCount

取消单个线程: 通过NSOperation的cancel方法

取消全部线程:通过NSOperationQueue的cancelAllOperations

暂停和继续:通过修改NSOperationQueue的suspended属性

五 GCD

GCD的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。

1、dispatch_async

子线程处理耗时操作(读取网络数据,数据库操作等),主线程用于更新UI。

[objc] view plaincopy
  1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    
  2.     // 耗时的操作    
  3.     dispatch_async(dispatch_get_main_queue(), ^{    
  4.         // 更新界面    
  5.     });    
  6. });    


eg:图片下载,子线程用于网络请求,主线程更新imageview
[objc] view plaincopy
  1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    
  2.     NSURL * url = [NSURL URLWithString:@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"];    
  3.     NSData * data = [[NSData alloc]initWithContentsOfURL:url];    
  4.     UIImage *image = [[UIImage alloc]initWithData:data];    
  5.     if (data != nil) {    
  6.         dispatch_async(dispatch_get_main_queue(), ^{    
  7.             self.imageView.image = image;    
  8.          });    
  9.     }    
  10. });    


2、dispatch_group_async

dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。
eg:执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了
[objc] view plaincopy
  1. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);    
  2. dispatch_group_t group = dispatch_group_create();    
  3. dispatch_group_async(group, queue, ^{    
  4.     [NSThread sleepForTimeInterval:1];    
  5.     NSLog(@"group1");    
  6. });    
  7. dispatch_group_async(group, queue, ^{    
  8.     [NSThread sleepForTimeInterval:2];    
  9.     NSLog(@"group2");    
  10. });    
  11. dispatch_group_async(group, queue, ^{    
  12.     [NSThread sleepForTimeInterval:3];    
  13.     NSLog(@"group3");    
  14. });    
  15. dispatch_group_notify(group, dispatch_get_main_queue(), ^{    
  16.     NSLog(@"updateUi");    
  17. });    
  18. dispatch_release(group);    
dispatch_group_async是异步的方法,运行后可以看到打印结果:

2012-09-25 16:04:16.737 gcdTest[43328:11303] group1
2012-09-25 16:04:17.738 gcdTest[43328:12a1b] group2
2012-09-25 16:04:18.738 gcdTest[43328:13003] group3
2012-09-25 16:04:18.739 gcdTest[43328:f803] updateUi

每个一秒打印一个,当第三个任务执行后,upadteUi被打印。



3、dispatch_barrier_async的使用

dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行

例子代码如下:

  1. dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);  
  2. dispatch_async(queue, ^{  
  3.     [NSThread sleepForTimeInterval:2];  
  4.     NSLog(@"dispatch_async1");  
  5. });  
  6. dispatch_async(queue, ^{  
  7.     [NSThread sleepForTimeInterval:4];  
  8.     NSLog(@"dispatch_async2");  
  9. });  
  10. dispatch_barrier_async(queue, ^{  
  11.     NSLog(@"dispatch_barrier_async");  
  12.     [NSThread sleepForTimeInterval:4];  
  13.   
  14. });  
  15. dispatch_async(queue, ^{  
  16.     [NSThread sleepForTimeInterval:1];  
  17.     NSLog(@"dispatch_async3");  
  18. });  

打印结果:

2012-09-25 16:20:33.967 gcdTest[45547:11203] dispatch_async1

2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_async2

2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_barrier_async

2012-09-25 16:20:40.970 gcdTest[45547:11303] dispatch_async3

请注意执行的时间,可以看到执行的顺序如上所述。


  

其他用法请参照官方文档GCD



部分内容参照博客,感谢原作者容芳志 http://blog.csdn.net/totogo2010/article/details/8016129

相关文章推荐

iOS多线程入门之NSThread,NSOperation,GCD

iOS的三种多线程技术特点: 1.NSThread: 1> 优点:NSThread对象建立一个线程非常方便; 2> 缺点:要使用NSThread管理多个线程非常困难,不推荐使用;...

iOS多线程学习-NSThread、Cocoa NSOperation、GCD

简介 iOS有三种多线程编程的技术,分别是: (一)NSThread (二)Cocoa NSOperation (三)GCD(全称:Grand Central Dispatch) 这三种...

iOS 多线程的实现与使用(NSThread, NSOperation, GCD)

首先我们先对进程,线程,多线程有个了解 进程:一个正在运行的程序 叫一个进程多进程:多个程序正在运行 叫多进程线程:一个程序 或者说 一个进程 都会有一个 或多个线程 如果有一个 我们叫他主线程 主...

iOS多线程NSThread,NSOperation和GCD详解

线程是特别有用的,当你需要执行一个特别耗时的任务,但又不希望它阻塞程序的其余部分功能的执行。特别是,你可以使用线程来避免阻塞应用程序的主线程去处理用户界面的事件和有关的行动的功能。线程还可以用于将大型...

ios笔记-- 多线程应该知道的那几件事 GCD NSThread NSOperation

iphone5s 出来了,CPU 升级到了64位 可以应用到更大的内存了,同时对多线程的处理吞吐能力也教之前提升了十几倍。下面着中总结下ios 下多线程的知识点 1:现有的几种多线程 ...

IOS 多线程NSThread、NSOperation、GCD详解

ios中多线程问题 IOS 多线程NSThread、NSOperation、GCD详解 iOS有三种多线程编程的技术,分别是: 1、NSThread 2、Cocoa NSOperation...

iOS之多线程开发(NSThread,NSOperation,GCD)

今天闲来无事,就来总结一下iOS中的多线程开发吧。 iOS有三种多线程编程的技术,分别是: 1.NSThread------每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.N...

iOS 多线程NSThread、NSOperation、GCD

1,NSThread 1.1初始化 NSThread *thread = [[NSThread alloc]initWithTarget:(id) selector:(SEL) object:...

iOS多线程(NSThread、NSOperation、GCD)

文章大纲 一、基本概念 计算机操作系统都有的基本概念,以下概念简单方式来描述。 进程: 一个具有一定独立功能的程序关于某个数据集合的一次运行活动。可以理解成一个运行中的应用程...
  • PRliu
  • PRliu
  • 2016-04-28 17:04
  • 201
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)