IOS 多线程技术

IOS有三种多线程编程技术,分别是:

    1)NSThread

    2)Cocoa NSOperation

    3)GCD(Grand Central Dispatch)

    这三种编程方式从上到下,抽象层次从低到高,抽度越高越简单,也是Apple最推荐使用的。


三种方式的优缺点介绍

    1)NSThread

        优点:比其他两种轻量级

        缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据加锁会有一定的系统开销。

    2)Cocoa NSOperation

        优点:不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。

                    Cocoa Operation相关的类是NSOperation, NSOperationQueue。NSOperation是个

                    抽象类,使用它必须用它的子类,可以试想他活着使用它定义好的两个字类:

                    NSInvocationOperation和NSBlockOperation。创建NSOperation子类的对象把对象添

                    加到NSOperationQueue对了里执行。

    3)GCD

        Grand Central Dispatch是Apple开发的一个多核编程解决方法。在IOS4.0中发布。GCD是一个

        替代注入NSThread,NSOperationQueue,NSInvocationOperation的技术的很高效和强大的技

        术。现在IOS系统升级到9了,所以不用担心该技术不能使用。


三种方式的使用

    1)NSThread:NSThread有两种创方式

1、[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];   


2、NSThread* myThread = [[NSThread alloc] initWithTarget:self   
                                        selector:@selector(doSomething:)   
                                        object:nil];   
   [myThread start];

        第一种是类方法,第二种是实例方法

        参数的意义:

        selector:线程执行的方法,这个selector只能有一个参数,而且不能有返回值。

        target:selector消息发送的对象

        argument:传输给target的唯一参数,也可以是nil


        不显示创建线程的方法:

        用NSObject的类方法performSelectorInBackground:withObject:创建一个线程:

[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];
        

    2)Cocoa NSOperation的使用

        使用NSOperation的方式有两种:一种是用定义好的两个子类:NSInvocationOperation和

        NSBlockOperation。另一种是继承NSOperation。如果你也熟悉Java,NSOperation就和

        Runnable很相似。NSOperation也是设计用来扩展的,只需要继承重写NSOperation的一

        个方法main。相当于Java中的Run方法。然后把NSOperation子类的对象放入NSOperationQueue

        队列中,该队列就会启动并开始处理它。

        下面看一个例子:

#import "ViewController.h"   
#define kURL @"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"   


@interface ViewController ()   


@end   


@implementation ViewController   


- (void)viewDidLoad   
{   
    [super viewDidLoad];   
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self   
                                                                           selector:@selector(downloadImage:)   
                                                                             object:kURL];   


    NSOperationQueue *queue = [[NSOperationQueue alloc]init];   
    [queue addOperation:operation];   
    // Do any additional setup after loading the view, typically from a nib.   
}   


-(void)downloadImage:(NSString *)url{   
    NSLog(@"url:%@", url);   
    NSURL *nsUrl = [NSURL URLWithString:url];   
    NSData *data = [[NSData alloc]initWithContentsOfURL:nsUrl];   
    UIImage * image = [[UIImage alloc]initWithData:data];   
    [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];   
}   
-(void)updateUI:(UIImage*) image{   
    self.imageView.image = image;   
}

 

    3)GCD的介绍和使用

        介绍:Grand Central Dispatch简称GCD是苹果公司开发的技术,以优化的应用程序支持多核新处理器

         和其他的对称多处理系统的系统。这建立在任务并行执行的线程池模式的基础上的。它首次发布

         在Mac OS X 10.6 iOS4上。

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

          理器核心上执行任务。一个任务可以是一个函数或者是一个block。GCD底层依然是用线程实现,不过

          这样可以让程序员不必关注实现细节。其中的FIFO队列称为dispatch queue,他可以保证先进先执行。

        

        dispatch queue分为下面三种:

            (1)Serial:同时只执行一个任务。通常用于同步访问特定的数据或资源。当创建多个serial queue时,

                     queue之间是并发执行的。

            (2)Concurrent:又称为global dispatch queue,可以并发地执行多任务,但是执行完成的顺序是随机的。

            (3)Main:他是全局可用的serial queue,他在应用程序的主线程上执行。

        

        使用:

        (1)常用的方法dispatch_async

            为了避免界面在处理耗时操作是卡死,比如读取网络数据,IO,数据库读写等。我们会在另外一个线程

            中处理这些操作,然后通知主线程更新界面。

            下面是例子:

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;   
         });   
    }   
});

            系统给每个应用程序提供三个concurrent dispatch queues。 这三个并发调度队列是全局的,他们只有优先级

            不同。应为是全局的所以我们不用去创建他。我们只需要通过函数dispatch_get_global_queue去取得队列。


        (2)dispatch_group_async的使用

            他可以实现监听一组任务是否完成,完成后得到通知执行其他操作。这方法很有用,比如你执行三个下载任务

            当三个任务都完成后你才通知界面说完成了。下面是例子:

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);

            下面是打印结果:

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

        (3)dispatch_barrier_async的使用

            他是在前面的任务执行结束后才执行,而且他后面的任务等待它执行完成后才执行,下面是一段例子:

dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);   
dispatch_async(queue, ^{   
    [NSThread sleepForTimeInterval:2];   
    NSLog(@"dispatch_async1");   
});   
dispatch_async(queue, ^{   
    [NSThread sleepForTimeInterval:4];   
    NSLog(@"dispatch_async2");   
});   
dispatch_barrier_async(queue, ^{   
    NSLog(@"dispatch_barrier_async");   
    [NSThread sleepForTimeInterval:4];   
});   
dispatch_async(queue, ^{   
    [NSThread sleepForTimeInterval:1];   
    NSLog(@"dispatch_async3");   
});

            打印结果:

2016-07-25 16:20:33.967 gcdTest[45547:11203] dispatch_async1 
2016-07-25 16:20:35.967 gcdTest[45547:11303] dispatch_async2 
2016-07-25 16:20:35.967 gcdTest[45547:11303] dispatch_barrier_async 
2016-07-25 16:20:40.970 gcdTest[45547:11303] dispatch_async3

        (4)dispatch_apply

            执行某段代码N次,下面是例子:

dispatch_apply(5, globalQ, ^(size_t index) { 
    // 执行5次 
});











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值