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

原创 2015年07月06日 16:36:34

一 线程的概念


一个运行着的程序就是一个进程或者叫做一个任务,一个进程至少包含一个线程,线程就是程序的执行流。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: 

1.1:[NSThread detachNewThreadSelector:@selector(threadInMainMethod:) toTarget:self withObject:nil];
 
1.2:NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(threadInMainMethod:) object:nil];
 [myThread start]; 
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 操作队列,就相当于一个线程管理器,而非一个线程。因为你可以设置这个线程管理器内可以并行运行的的线程数量等等。

[queue setMaxConcurrentOperationCount:1]; 

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

设置优先级:setQueuePriority:

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

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

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

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

五 GCD

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

1、dispatch_async

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

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
    // 耗时的操作  
    dispatch_async(dispatch_get_main_queue(), ^{  
        // 更新界面  
    });  
});  


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


2、dispatch_group_async

dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。
eg:执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
dispatch_group_t group = dispatch_group_create();  
dispatch_group_async(group, queue, ^{  
    [NSThread sleepForTimeInterval:1];  
    NSLog(@"group1");  
});  
dispatch_group_async(group, queue, ^{  
    [NSThread sleepForTimeInterval:2];  
    NSLog(@"group2");  
});  
dispatch_group_async(group, queue, ^{  
    [NSThread sleepForTimeInterval:3];  
    NSLog(@"group3");  
});  
dispatch_group_notify(group, dispatch_get_main_queue(), ^{  
    NSLog(@"updateUi");  
});  
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、Cocoa NSOperation、GCD三者使用详解

简介 iOS有三种多线程编程的技术,分别是: (一)NSThread (二)Cocoa NSOperation (三)GCD(全称:Grand Central Dispatch)...
  • lgm252008
  • lgm252008
  • 2014年10月13日 09:18
  • 14363

iOS并发编程对比总结,NSThread,NSOperation,GCD - iOS

1. 多线程概念进程 正在进行中的程序被称为进程,负责程序运行的内存分配 每一个进程都有自己独立的虚拟内存空间 线程 线程是进程中一个独立的执行路径(控制单元) 一个进程中至少包含一条线程,即主线程 ...
  • zyq522376829
  • zyq522376829
  • 2016年08月30日 21:26
  • 2383

iOS面试题11- NSThread/NSOperation/GCD的优缺点总结

iOS面试题11- NSThread/NSOperation/GCD的优缺点总结 •NSThread: –优点:NSThread 比其他两个轻量级,使用简单 –缺点:需要自己管理线程的生命周期...
  • Nathan1987_
  • Nathan1987_
  • 2015年12月30日 17:28
  • 1914

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

今天闲来无事,就来总结一下iOS中的多线程开发吧。 iOS有三种多线程编程的技术,分别是: 1.NSThread------每个NSThread对象对应一个线程,量级较轻(真正的多线程...
  • wei78008023
  • wei78008023
  • 2016年03月03日 17:32
  • 852

iOS开发之NSThread、NSOperation、GCD三者之间的简略比较

1、首先NSThread、NSOperation、GCD这三种方式的发展历程是由早到晚的,因此后者相比较前者而言更加简单易用,即GCD为当前苹果较为推荐的一种方式。 2、NSThread在控制线程优...
  • u012891546
  • u012891546
  • 2016年03月18日 17:52
  • 634

Objective-C多线程详解(NSThread、NSOperation、GCD)

进程和线程 程序:一个由源代码生成的可执行应用(比如qq,微信…) 进程:进程是指在系统中正在运行的一个应用程序。一个正在运行的程序可以看成一个进程,进程负责去向手机系统申请资源,同时将这...
  • liu1347508335
  • liu1347508335
  • 2016年01月21日 14:33
  • 2167

【OC】IOS多线程之NSoperation和GCD的比较

GCD是基于c的底层api,NSOperation属于object-c类。ios 首先引入的是NSOperation,IOS4之后引入了GCD和NSOperationQueue并且其内部是用gcd实现...
  • chenglibin1988
  • chenglibin1988
  • 2013年10月12日 17:19
  • 14451

IOS学习 NSOperation 并发数量、暂停/继续、取消、等待、依赖 与GCD区别

@interface ViewController () //定义一个全局的队列 @property (nonatomic,strong)NSOperationQueue *opQueu...
  • ridxmc
  • ridxmc
  • 2016年04月06日 22:16
  • 3144

iOS 开发之多线程 (GCD与NSOperation)详解

本文转自:http://dev.dafan.info/detail/226124?p=18 概述 何为多线程? 多线程其实针对单核的CPU来设计的,CPPU同一时间只能执行一...
  • Xia0Liang
  • Xia0Liang
  • 2017年04月19日 11:37
  • 924

【iOS】多线程NSOperation 与 GCD的区别

NSOperation是苹果封装的一套多线程的东西,不像GCD是纯C语言的,这个是OC的。但相比较之下GCD会更快一些,但本质上NSOPeration是多GDC的封装。 一、NSOperatio...
  • sevenquan
  • sevenquan
  • 2015年12月23日 16:32
  • 2029
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS多线程入门之NSThread,NSOperation,GCD
举报原因:
原因补充:

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