码迷,mamicode.com
首页 > 移动开发 > 详细

iOS多线程技术

时间:2015-01-25 01:15:53      阅读:482      评论:0      收藏:0      [点我收藏+]

标签:

说明:开发技术大同小异,帖子写出来不是为了晒的,只是一个学习记录过程,有错误欢迎指正,喜欢喷人的请滚蛋。

一、实现方案

在iOS中有三种多线程实现技术,它们分别是NSThread、GCD 、NSOperation。

  NSThread:基于OC编写,更加面向对象,可直接操作线程对象,需要程序员手动管理线程生命周期,开发中偶尔使用。

  GCD:基于c语言编写,旨在替代NSThread线程技术,能充分利用设备的多核,系统自动管理线程生命周期,开发中经常使用。

  NSOperation:底层基于GCD封装的一套OC实现,更加面向对象,系统自动管理线程生命周期,开发中经常使用。

1.NSThread

一个NSthread对象就代表一条线程

相关设置

 

设置线程的名字

 

- (void)setName:(NSString *)name;

 

- (NSString *)name;

 

获得当前线程

 

[NSThread currentThread];

 

线程调度优先级:优先级范围在0.0~1.0之间,默认是0.5,值越大,优先级越高,越容易被调度。

 

- (void)setThreadPriority:(double)priority

 

- (double)threadPriority

 

主线程

 

+ (NSThread *)mainThread; // 获得主线程

 

- (BOOL)isMainThread; // 是否为主线程

 

+ (BOOL)isMainThread; // 是否为主线程

 

1.线程的创建

 1>NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(callback) object:nil];

 [thread start];

2>[NSThread detachNewThreadSelector:@selector(callback:) toTarget:self withObject:nil];

3>[self performSelectorInBackground:@selector(callback:) withObject:nil];

第一种相比较后两种而言可以更加精准的控制线程相关设置,比如线程名称,优先级等。

2.线程的状态

新建:线程创建出来

就绪:调用线程start方法,加载到线程池等待调度

运行:线程得到cpu调度

阻塞:线程睡眠或等待同步锁

死亡:线程执行完毕或者强制退出或者程序崩溃

3.线程的同步

当多个线程访问共享资源时,会有数据安全问题,例如写出错,读取脏数据,解决办法是加互斥锁。

//加锁

 @synchronized(self){

  访问共享资源代码

}//解锁

4.线程的通信

有时候多个线程之间需要相互通信,互相传递数据,比如在子线程下载好图片资源后需要回到主线程更新UI界面

可以在子线程内部发发异步请求向主线程传递数据。

- (void)threadCommunicate

{

    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(download) object:nil];

    [thread setThreadPriority:1];

    thread.name = @"线程A";

    [thread start];

}

- (void)download

{

    //1.下载图片

    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png"]];

    UIImage *image = [UIImage imageWithData:data];

    //2.更新图片(子线程下载的图片返回给主线程更新UI界面)

    [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];

}

2.GCD(Grand Central Dispatch)

GCD会充分利用设备的多核技术,自动管理线程的生命周期,程序员只需要将任务放在相关队列中就可以了,不用关心线程的状态

首先理解两个概念

队列:

串行队列:队列的任务串行执行

并发队列:队列的任务并发执行

请求:

同步:不会开启新线程

异步:会开启新线程,只有放在并发队列中才会实现多线程技术,放在串行队列中只会开启一个线程且任务串行执行。

- (void)viewDidLoad
{
    [super viewDidLoad];
    //1.串行队列(队列里面的操作串行执行)
    self.serialQueue = dispatch_queue_create("串行对列",DISPATCH_QUEUE_SERIAL);
    //2.并发队列(队列里面的操作并发执行)
    self.concurrentQueue = dispatch_queue_create("并行队列",DISPATCH_QUEUE_CONCURRENT);
    //3.全局队列(系统自带并发队列)
    self.globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //4.主队列(与主线程相关)
    self.mainQueue = dispatch_get_main_queue();
    NSLog(@"主线程%@",[NSThread currentThread]);
    //[self gcdCommunicate];
}

/**
 * 同步函数dispatch_sync不会开启新线程
 */
- (void)sync
{
    //在串行队列中同步执行操作
    for(int i = 0;i<10;i++){
        dispatch_sync(self.serialQueue, ^{
            NSLog(@"同步串行%@--%d",[NSThread currentThread],i);
        });
    }
    //在并发队列中同步执行操作
    for(int i = 0;i<10;i++){
        dispatch_sync(self.concurrentQueue, ^{
            NSLog(@"同步并发%@",[NSThread currentThread]);
        });
    }
    //在全局队列中同步执行操作
    for(int i = 0;i<10;i++){
        dispatch_sync(self.globalQueue, ^{
            NSLog(@"同步全局%@",[NSThread currentThread]);
        });
    }
    //在主队列中同步执行操作
#warning 在主线程中执行同步操作会卡住
    dispatch_sync(self.mainQueue, ^{
        NSLog(@"同步主%@",[NSThread currentThread]);
    });
}
/**
 * 异步函数dispatch_async会开启新线程
 */
- (void)async
{
    //在串行队列中异步执行操作(开启一条子线程,操作串行执行)
    for(int i = 0;i<10;i++){
        dispatch_async(self.serialQueue, ^{
            NSLog(@"异步串行%@---%d",[NSThread currentThread],i);
        });
    }
    //在并发队列中异步执行操作(开启多条子线程,操作并发执行)
    for(int i = 0;i<10;i++){
        dispatch_async(self.concurrentQueue, ^{
            NSLog(@"异步并发%@---%d",[NSThread currentThread],i);
        });
    }
    //在全局队列中异步执行操作(开启多条子线程,操作并发执行)
    for(int i = 0;i<10;i++){
        dispatch_async(self.globalQueue, ^{
            NSLog(@"异步全局%@---%d",[NSThread currentThread],i);
        });
    }
    //在主队列中异步执行操作(在主线程上执行,操作串行执行)
    for(int i = 0;i<10;i++){
        dispatch_async(self.globalQueue, ^{
            NSLog(@"异步主%@---%d",[NSThread currentThread],i);
        });
    }
}

/**
 * GCD的线程通信
 */
- (void)gcdCommunicate
{
    dispatch_async(self.globalQueue, ^{
        NSLog(@"当前线程%@", [NSThread currentThread]);
        // 下载图片
        NSURL *url = [NSURL URLWithString:@"http://news.baidu.com/z/resource/r/image/2014-06-22/2a1009253cf9fc7c97893a4f0fe3a7b1.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url]; 
        UIImage *image = [UIImage imageWithData:data];
        
        // 回到主线程显示图片
        dispatch_async(self.mainQueue, ^{
            NSLog(@"当前线程%@", [NSThread currentThread]);
            self.imageView.image = image;
        });
    });
}

3.NSOperation

NSOperation底层基于GCD,使用OC编写,更加面向对象,是苹果官方比较推荐的技术

配合使用NSOperation和NSOperationQueue也能实现多线程编程

1>使用步骤

 首先创建NSOperation对象,将操作封装到里面

然后将NSOperation对象添加到NSOperationQueue中

系统会自动将NSOperation中封装的操作放到一条新线程中执行

2>子类

NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类

使用NSOperation子类的方式有3种

NSInvocationOperation

NSBlockOperation

自定义子类继承NSOperation,实现内部相应的方法

/**
 * NSInvocationOperation的使用
 */
- (void)invocationOperation
{
    // 1.创建操作对象, 封装要执行的操作
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(callback) object:nil];
    // 2.启动操作(默认情况下,如果操作没有放到队列queue中,都是同步执行)
    [operation start];
}
- (void)callback
{
    NSLog(@"当前线程%@",[NSThread currentThread]);
}
/**
 * NSBlockOperation的使用
 */
- (void)blockOperation
{
    // 1.创建操作对象, 封装要执行的操作
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"当前线程%@--操作1",[NSThread currentThread]);
    }];
    [operation addExecutionBlock:^{
        NSLog(@"当前线程%@--操作2",[NSThread currentThread]);
    }];
    [operation addExecutionBlock:^{
        NSLog(@"当前线程%@--操作3",[NSThread currentThread]);
    }];
    //监听操作
    operation.completionBlock = ^(){
        NSLog(@"当前线程%@--操作完毕", [NSThread currentThread]);
    };
    // 2.启动操作(如果只有一个操作不会开启线程,如果有多个操作,就会开启新线程)
    [operation start];
}
/**
 * NSOperationQueue的使用
 */
- (void)OperationQueue
{
    //1.创建操作队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    //设置队列的最大并发数
    queue.maxConcurrentOperationCount = 3;
    //2.创建操作
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"当前线程%@-操作1",[NSThread currentThread]);
    }];
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"当前线程%@-操作2",[NSThread currentThread]);
    }];
    NSInvocationOperation *operation3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocation) object:nil];
    
    //设置依赖
    //[operation2 addDependency:operation1];
    //[operation3 addDependency:operation2];
    
    
    //3.操作放在队列中
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
}
- (void)invocation
{
    NSLog(@"当前线程%@-操作3",[NSThread currentThread]);
}

//写的有点晚了,本来想写细点,不过感觉这些代码和思想都很简单,方便以后自己重温就行了,所以写的糙了点,海涵。

 

iOS多线程技术

标签:

原文地址:http://www.cnblogs.com/wc85328/p/4246896.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!