【第22期】观点:IT 行业加班,到底有没有价值?

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





版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

多线程编程1 - NSThread

每个iOS应用程序都有个专门用来更新显示UI界面、处理用户的触摸事件的主线程,因此不能将其他太耗时的操作放在主线程中执行,不然会造成主线程堵塞(出现卡机现象),带来极坏的用户体验。一般的解决方案就是将...

swift开发多线程篇 - NSThread 线程相关简单说明(一些使用和注意点)

一 说明 本文涉及代码可以从https://github.com/HanGangAndHanMeimei/Code地址获得。 二 NSThread的基本使用和创建   1)基本用法(主线程|当前...

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

NSThread和线程锁

一、NSThread 多线程的优缺点: 优点:NSThread比NSOperation和GCD轻量级; 缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销。 二、NST...

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

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

iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD

原文:http://blog.jobbole.com/69019/ 简介 iOS有三种多线程编程的技术,分别是: (一)NSThread (二)Cocoa NSOperation (...

iOS多线程之NSThread的使用

iOS 多线程之NSThread

iOS中的多线程技之Pthread和NSThread

什么是进程? 进程是指系统中正在运行的一个应用程序? 什么是线程? 线程是指程序的一段执行序列(代码逻辑),进程的一部分。 iOS中主线程和子线程的责任分工: 主线程:显示/刷新UI界面;处理UI事件...

iOS多线程编程技术NSThread、Cocoa NSOperation、GCD三者使用详解

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

阿里IOS面试题之多线程选用NSOperation or GCD

今天早上接到了阿里从杭州打过来的电话面试.虽然近期面试了一些大中型的互联网企业,但是跟素有“IT界的黄浦军校”的
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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