iOS多线程编程

来源:互联网 发布:unblockcn mac 编辑:程序博客网 时间:2024/05/01 18:47

iOS大致提供了如下3种多线程编程的技术:

1.使用NSThread实现多编程

2.使用GCD(Grand Center Dispatch)实现多线程

3.使用NSOperation与NSOperationQueue实现多线程


下面介绍第一种方法:使用NSThread实现多线程

创建NSThread有两种方法:

1.-(id) initWithTarget:(id)target selector:(SEL)selector object:(id)arg:  创建一个新线程对象。2.+(void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)arg:  创建并启动新线程。

第一种方法必须调用start方法启动线程;第二种方法会直接创建并启动线程。


实例:

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];for (int i = 0; i < 100; i++) {        NSLog(@"===thread 1===%d",i);        if (i == 20) {            //创建线程对象           // NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];            //启动新线程            //[thread start];            //创建并启动新线程            [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];        }    }}- (void)didReceiveMemoryWarning{    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}- (void) run{    for (int i = 1; i < 100; i++) {        NSLog(@"---thread 2---%d",i);    }}@end

运行结果:



第二种方法:使用GCD(Grand Center Dispatch)实现多线程

iOS提供了GCD来实现多线程。GCD的两个核心概念如下:

队列:队列负责管理开发者提交的任务,GCD队列始终以FIFO(先进先出)的方式来处理任务。队列既可以是串行队列,也可以是并发队列。串行队列每次只处理一个任务,必须前一个执行完成后,才能执行下一个;并发队列则可同时处理多个任务,因此将会有很多个任务并发执行。

任务:任务就是用户提交给队列的工作单元,这些任务将会提交给队列底层维护的线程池执行,因此这些任务会以多线程的方式执行。

使用GCD实现多线程的两个步骤:

1.创建队列;

2.将任务提交给队列。

程序可以创建如下几种队列:

(1)获取系统默认的全局并发队列

diapatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEAFULT, 0)


(2)获取系统主线程关联的串行队列

diapatch_queue_t queue = dispatch_get_main_queue();

(3)创建串行队列

diapatch_queue_t queue = dispatch_queue_create("my.queue", DISPATCH_QUEUE_SERIAL);
如果将多个任务提交给串行队列,多个任务只能顺序执行,必须等前一个任务完成后,才能开始执行后一个任务。

(4)创建并行队列

diapatch_queue_t queue = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT);
如果将多个任务提交给并发队列,队列可按FIFO顺序启动多个并发执行的任务。


实例:点击download按钮,下载百度logo图片。程序界面中添加一个UIImageView和UIButton。

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];}- (void)didReceiveMemoryWarning{    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}- (IBAction)downImage:(id)sender {    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(void){        NSString *url = @"http://www.baidu.com/img/baidu_sylogo1.gif";        NSLog(@"%@",url);        //从网络获取数据        NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];        //将网络数据初始化为UIImage对象        UIImage *image = [[UIImage alloc]initWithData:data];        if(image != nil)        {            dispatch_async(dispatch_get_main_queue(), ^{                self.iv.image = image;            });        }        else        {            NSLog(@"---下载图片出现错误---");        }    });}                   @end

运行结果:


第三种方法:使用NSOperation与NSOperationQueue实现多线程

NSOperation与NSOperationQueue也是一种简单的多线程实现方法。

NSOperationQueue:代表一个FIFO的队列,负责管理系统提交的多个NSOperation,NSOperation底层维护一个线程池,会按顺序启动线程来执行提交给该队列的NSOperation队列。

NSOperation:代表一个多线程任务。

实现多线程步骤:

1.创建NSOperationQueue队列,并为该队列设置相关属性;

2.创建NSOperation子类的对象,并将该对象提交给NSOperationQueue队列。

实例:点击download按钮,下载百度logo图片。

#import "ViewController.h"@interface ViewController ()@endNSOperationQueue *queue;@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];    queue = [[NSOperationQueue alloc] init];    //设置队列最大支持1-个并发线程    queue.maxConcurrentOperationCount = 10;}- (void)didReceiveMemoryWarning{    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}- (IBAction)click:(id)sender {    NSString *url = @"http://www.baidu.com/img/baidu_sylogo1.gif";    NSLog(@"%@",url);    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{        //网络获取数据        NSData *data = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:url]];        //将网络数据初始化为UIImage对象        UIImage *image = [[UIImage alloc]initWithData:data];        if(image != nil)        {            //在主线程中执行updataUI方法            [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];        }        else        {            NSLog(@"---下载图片出错---");        }    }];    [queue addOperation:operation];}- (void)updateUI:(UIImage *) image{    self.imageView.image = image;}@end

运行结果与第二种方法效果一样。



0 0