IOS多线程处理 三种多线程的实例
2014-11-20 15:31
253 查看
在Object-c中,常用的多线程处理类分别为NSThread和NSOperationQueue。使用这两个类处理多线程,让复杂的多线程处理变得简单高效。下面分别介绍。
一、NSThread类苹果公司的Cocoa框架共支持三种多线程机制,分别为NSThread、GCD(Grand Central Dispatch)、Cocoa NSOperatio。NSThree是官方推荐的线程处理方式,它在处理机制上,需要开发者负责手动管理Thread的生命周期,包括子线程与主线程之间的同步等。线程共享同一应用程序的部分内存空间,它们拥有对数据相同的访问权限。你得协调多个线程 对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销。在 iOS 中我们可以使用多种形式的 thread。初次接触的读者也许会觉得生涩,但事实上NSThread类已经提供了完善的接口,在使用方式上并不会太难。使用NSTread管理线程,主要的步骤如下。1)声明一个NSCondition同步锁;2)声明若干个NSThread子线程;3)指定NSThread子线程的目标指行方法(可以在构造函数中指定);4)设置子线程的名称;5)star启动子线程。其中,子线程的执行方法一般只需要一个共同方法即可(可以通过线程名,分辨当前的执行线程)。下面通过代码演示NSThread类的使用。假设我们需要下载网络图片,在非异步形式的情况下,IOS界面必须等到图片下载完毕后,UI才会反应。这时利用多线程就可以达到异步下载的效果。ViewController1.h
ViewController1.m
二、NSOperationQueue类如果需要让线程同时并行运行多个,可以将线程加入队列(Queue)中,NSOperationQueue类就是一个线程队列管理类,他提供了线程并行、队列的管理。可以认为NSOperationQueue就是一个线程管理器,通过addOperations方法,我们可以一次性把多个(数组形式)线程添加到队列中。同时,NSOperationQueue允许通过setMaxConcurrentOperationCount方法设置队列的并行(同一时间)运行数量。NSOperationQueue的使用步骤如下。1)声明一个NSOperationQueue对象;2)声明若干个NSInvocationOperation子线程对象,并指定回调方法;3)将NSInvocationOperation子线程添加到数组;4)把数组赋给NSOperationQueue类中的addOperations方法;5) 实现回调方法;6)在回调方法中实现performSelectorOnMainThread方法,更新主线程上的界面UI元素。
下面,使用NSOperationQueue类,实现前面NSThread类相同的功能(即下载图片)。代码如下。
ViewController2.m
[self performSelectorOnMainThread:@selector(updateLabel:)withObject:updateData waitUntilDone:YES]; 该方法是一个主线程同步方法,不仅可以应用在NSOpeartionQueue中,同样还适用于NSThread类。
Grand Central Dispatch,或者简称 GCD,是一个与 Block Object 产生工作的低级的 C API。GCD 真正的用途是将任务分配到多个核心又不让程序员担心哪个内核执行哪个任务。 在 Max OS X 上,多内核设备,包括笔记本,用户已经使用了相当长的时间。通过多核设备 比如 iPad2 的介绍,程序员能为 iOS 写出神奇的多核多线程 APP。
一、线程管理常用方法
1.performSelector(InBackground or MainThread)
这个方法比较方便,但是问题在于参数传递只能支持一个对象(传多个参数,我是将其打包在一个NSDictionary里面)
2.NSOperationQueue
这个方法稍微复杂,提供了每个任务的封装(NSOperation)。可以继承NSOperation之后,在main函数中写一些同步执行的代码,然后放到一个Queue之中,Queue自动管理Operation的执行和调度(在UI线程以外)。对于异步执行的代码,需要重载NSOperation的好几个函数才能正常工作(告诉Queue关于这个任务的进度以及执行情况)。
3.NSThread
轻量级的线程管理机制
4.GCD
在UI线程和其它线程之间切换很方便,可以和NSOperationQueue搭配使用。本文着重介绍这个方法。5,pthread
二、GCD使用示例GCD 的核心是分派队列。不论在 iOS 还是 Max OS X 分派队列,正如我们快看到的是 由位于主操作系统的 GCD 来管理的线程池。你不会直接与线程有工作关系。你只在分派队 列上工作,将任务分派到这个队列上并要求队列来调用你的任务。GCD 为运行任务提供了 几个选择:同步执行、异步执行和延迟执行等。
1、网络下载以点击一个按钮,然后显示loading,同时在后台下载一张图片,最后将下载的图片放到UIImageView中显示为例。
2、延迟执行
3、自定义GCD可以使用dispatch_queue_create函数创建自定义的GCD
4、线程合并利用GCD并行多个线程并且等待所有线程结束之后再执行其它任务
一、NSThread类苹果公司的Cocoa框架共支持三种多线程机制,分别为NSThread、GCD(Grand Central Dispatch)、Cocoa NSOperatio。NSThree是官方推荐的线程处理方式,它在处理机制上,需要开发者负责手动管理Thread的生命周期,包括子线程与主线程之间的同步等。线程共享同一应用程序的部分内存空间,它们拥有对数据相同的访问权限。你得协调多个线程 对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销。在 iOS 中我们可以使用多种形式的 thread。初次接触的读者也许会觉得生涩,但事实上NSThread类已经提供了完善的接口,在使用方式上并不会太难。使用NSTread管理线程,主要的步骤如下。1)声明一个NSCondition同步锁;2)声明若干个NSThread子线程;3)指定NSThread子线程的目标指行方法(可以在构造函数中指定);4)设置子线程的名称;5)star启动子线程。其中,子线程的执行方法一般只需要一个共同方法即可(可以通过线程名,分辨当前的执行线程)。下面通过代码演示NSThread类的使用。假设我们需要下载网络图片,在非异步形式的情况下,IOS界面必须等到图片下载完毕后,UI才会反应。这时利用多线程就可以达到异步下载的效果。ViewController1.h
#import <UIKit/UIKit.h> @interface ViewController1 : UIViewController{ NSCondition *_condition; NSThread *_thread_1; NSThread *_thread_2; } @end |
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 | / // ViewController1.m // Thread_demo // // Created by MAC on 13-4-22. // Copyright (c) 2013年 李开涌. All rights reserved. // #import "ViewController1.h" @interface ViewController1 () @end @implementation ViewController1 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization self.title=@"多线程NSThread"; } return self; } - (void)viewDidLoad { [super viewDidLoad]; //创建一个进程锁,实现线程同步 _condition=[[NSCondition alloc] init]; //创建线程1 _thread_1=[[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil]; [_thread_1 setName:@"thread_1"]; [_thread_1 start]; //创建线程2 _thread_2=[[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil]; [_thread_2 setName:@"thread_2"]; [_thread_2 start]; } #pragma mark--线程执行方法 -(void)run{ //进程上锁 [_condition lock]; NSLog(@"运行的线程名:%@",[[NSThread currentThread]name]); if ([[[NSThread currentThread]name] isEqualToString:@"thread_1"]) { NSLog(@"111"); NSURL *imageUrl_1=[NSURL URLWithString:@"http://t.beauty-soft.net/upload/ceiba20130224_014522_8679.jpg"]; NSData *data_1=[NSData dataWithContentsOfURL:imageUrl_1]; UIImage *image_1=[UIImage imageWithData:data_1]; UIImageView *imageView_1=[[UIImageView alloc] initWithImage:image_1]; imageView_1.frame=CGRectMake(60, 20, 200, 200); [self.view addSubview:imageView_1]; [imageView_1 release]; }else if([[[NSThread currentThread]name] isEqualToString:@"thread_2"]){ NSLog(@"222"); NSURL *imageUrl_2=[NSURL URLWithString:@"http://t.beauty-soft.net/upload/ceiba20120704_121437_3455.jpg"]; NSData *data_2=[NSData dataWithContentsOfURL:imageUrl_2]; UIImage *image_2=[UIImage imageWithData:data_2]; UIImageView *imageView_2=[[UIImageView alloc] initWithImage:image_2]; imageView_2.frame=CGRectMake(60, 250, 200, 200); [self.view addSubview:imageView_2]; [imageView_2 release]; } //解锁 [_condition unlock]; } -(void)dealloc{ [_thread_1 release]; [_thread_2 release]; [_condition release]; [super dealloc]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end |
下面,使用NSOperationQueue类,实现前面NSThread类相同的功能(即下载图片)。代码如下。
ViewController2.m
//// ViewController2.m // Thread_demo // // Created by MAC on 13-4-22. // Copyright (c) 2013年 李开涌. All rights reserved. // #import "ViewController2.h" @interface ViewController2 () @end @implementation ViewController2 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization self.title=@"线程队列"; } return self; } - (void)viewDidLoad { [super viewDidLoad]; // 线程队列管理器,实现线程并行运行 _opeartionQueue=[[NSOperationQueue alloc] init]; //队列最大同时运行数量 [_opeartionQueue setMaxConcurrentOperationCount:1]; tags=20; //创建线程1 NSInvocationOperation *invocationOpearation_1=[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"http://t.beauty-soft.net/upload/ceiba20130224_014522_8679.jpg"] autorelease]; //创建线程2 NSInvocationOperation *invocationOpearation_2=[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"http://t.beauty-soft.net/upload/ceiba20120704_121437_3455.jpg"] autorelease]; NSArray *array=@[invocationOpearation_1,invocationOpearation_2]; //把程序添加到管理器中 [_opeartionQueue addOperations:array waitUntilFinished:YES]; } -(void)run:(NSString *)imageStrinUrl{ NSLog(@"%@",[_opeartionQueue operations]); NSLog(@"mainQueue%@",[NSOperationQueue mainQueue]); NSLog(@"i==%i",tags); NSLog(@"urlStr:%@",imageStrinUrl); NSURL *url=[NSURL URLWithString:imageStrinUrl]; NSData *data=[NSData dataWithContentsOfURL:url]; UIImage *image=[UIImage imageWithData:data]; UIImageView *imageView=[[[UIImageView alloc] initWithImage:image]autorelease]; imageView.frame=CGRectMake(60, tags, 200, 200); tags+=200; //通知主线程更新UI [self performSelectorOnMainThread:@selector(updateUI:) withObject:imageView waitUntilDone:NO]; } -(void)updateUI:(UIImageView *)imageView{ [self.view addSubview:imageView]; } - (void)dealloc { [_opeartionQueue release]; [super dealloc]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end |
Grand Central Dispatch,或者简称 GCD,是一个与 Block Object 产生工作的低级的 C API。GCD 真正的用途是将任务分配到多个核心又不让程序员担心哪个内核执行哪个任务。 在 Max OS X 上,多内核设备,包括笔记本,用户已经使用了相当长的时间。通过多核设备 比如 iPad2 的介绍,程序员能为 iOS 写出神奇的多核多线程 APP。
一、线程管理常用方法
1.performSelector(InBackground or MainThread)
这个方法比较方便,但是问题在于参数传递只能支持一个对象(传多个参数,我是将其打包在一个NSDictionary里面)
2.NSOperationQueue
这个方法稍微复杂,提供了每个任务的封装(NSOperation)。可以继承NSOperation之后,在main函数中写一些同步执行的代码,然后放到一个Queue之中,Queue自动管理Operation的执行和调度(在UI线程以外)。对于异步执行的代码,需要重载NSOperation的好几个函数才能正常工作(告诉Queue关于这个任务的进度以及执行情况)。
3.NSThread
轻量级的线程管理机制
4.GCD
在UI线程和其它线程之间切换很方便,可以和NSOperationQueue搭配使用。本文着重介绍这个方法。5,pthread
二、GCD使用示例GCD 的核心是分派队列。不论在 iOS 还是 Max OS X 分派队列,正如我们快看到的是 由位于主操作系统的 GCD 来管理的线程池。你不会直接与线程有工作关系。你只在分派队 列上工作,将任务分派到这个队列上并要求队列来调用你的任务。GCD 为运行任务提供了 几个选择:同步执行、异步执行和延迟执行等。
1、网络下载以点击一个按钮,然后显示loading,同时在后台下载一张图片,最后将下载的图片放到UIImageView中显示为例。
//显示loading self.indicator.hidden = NO; [self.indicator startAnimating]; //进入异步线程 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //异步下载图片 NSURL * url = [NSURL URLWithString:@"http://anImageUrl"]; NSData * data = [NSData dataWithContentsOfURL:url]; //网络请求之后进入主线程 dispatch_async(dispatch_get_main_queue(), ^{ //关闭loading [self.indicator stopAnimating]; self.indicator.hidden = YES; if (data) {//显示图片 self.imageView.image = [UIImage imageWithData:data]; } }); }); |
// 延迟2秒执行: double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ // code to be executed on the main queue after delay }); |
dispatch_queue_t custom_queue = dispatch_queue_create(“customQueue”, NULL); dispatch_async(custom_queue, ^{ //doing something in custom_queue }); dispatch_release(custom_queue); |
dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ // 并行执行的线程一 }); dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ // 并行执行的线程二 }); dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{ // 汇总结果 }); |
相关文章推荐
- IOS处理音乐播放中断实例
- 多线程之旅七——GUI线程模型,消息的投递(post)与处理(IOS开发前传)
- 三种iOS多线程实现的方法
- IOS多线程的三种方式
- 时区日期处理及定时 (NSDate,NSCalendar,NSTimer,NSTimeZone) -- IOS(实例)
- Linux下C程序使用多线程方式处理实例
- IOS多线程编程之三种实现方式NSThread、NSOperation、Grand Central Dispatch
- 单例模式,多线程同时访问一个实例对象问题的处理,加lock .
- 时区日期处理及定时 (NSDate,NSCalendar,NSTimer,NSTimeZone) -- IOS(实例)
- (委托事件处理)关于多线程执行显示进度条的实例(转)&&线程间操作无效: 从不是创建控件“rtxtEntryNO”的线程访问它。
- 时区日期处理及定时 (NSDate,NSCalendar,NSTimer,NSTimeZone) -- IOS(实例)
- ios实例开发精品文章推荐(8.12)11个处理触摸事件和多点触摸的JS库
- iOS三种多线程编程的技术
- 多线程的使用(4) - iOS多线程的三种方式
- 多线程的使用(4) - iOS多线程的三种方式
- 时区日期处理及定时 (NSDate,NSCalendar,NSTimer,NSTimeZone) -- IOS(实例)
- 时区日期处理及定时 (NSDate,NSCalendar,NSTimer,NSTimeZone) -- IOS(实例)
- iOS三种多线程编程的技术
- iOS中NSAttributedString的使用--对关键字着色,以及处理html实例
- ios中4种开启新的线程的处理方式以及运用范围(多线程)