iOS多线程技术

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

一、实现方案

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

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

时间: 2024-10-28 23:34:32

iOS多线程技术的相关文章

iOS 多线程技术2

iOS 多线程技术2 NSOperation NSInvocationOperation //创建一个队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; //创建子任务,定义子任务必须是 NSOperation 的子类 NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(dosome

OA01-一个Demo展示iOS多线程技术的基本应用场景

最近在看iOS关于GCD.NSOperation多线程编程技术编程指南的时候写了个 小Demo,以7个小场景基本涵盖多线程技术的主流用法:其实多线程技术早在大学 读书的时候,基本思路就已经清晰了,不同操作系统的多线程实现也大同小异,iOS 平台下原理也是一样,关键就在与,能否熟练的.很顺畅的根据应用场景来选用相应 的多线程技术.阅读苹果官方文档和一些别人写的博客的时候也依然有种隔靴捞痒的 感觉:书读百边,不如实践一遍啊,SO,尽管网上相关的博客一大堆(首推这篇: http://www.cocoa

iOS多线程技术—线程的状态

iOS多线程技术—线程的状态 一.简单介绍 线程的创建: self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil]; 说明:创建线程有多种方式,这里不做过多的介绍. 线程的开启: [self.thread start]; 线程的运行和阻塞: (1)设置线程阻塞1,阻塞2秒 [NSThread sleepForTimeInterval:2.0]; (2)第二种设置线程阻塞2,以当前时间

iOS多线程技术—单例模式(ARC)与(MRC)

iOS多线程技术—单例模式(ARC) 一.简单说明: 设计模式:多年软件开发,总结出来的一套经验.方法和工具 java中有23种设计模式,在ios中最常用的是单例模式和代理模式. 二.单例模式说明 (1)单例模式的作用 :可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源. (2)单例模式的使用场合:在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次),应该让这个类创建出来的对象永远只有一个. (3)单例模式在ARC\MRC环

iOS多线程技术—自定义NSOperation

iOS多线程技术—自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UITableViewController. // // YYViewController.h // 01-自定义Operation // // Created by apple on 14-6-26. // Copyright (c) 2014年 itcase. All rights reserved.

iOS多线程技术—GCD介绍

iOS多线程技术—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自动利用更多的CPU内核(比如双核.四核) GCD会自动管理线程的生命周期(创建线程.调度任务.销毁线程) 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码 3.提示 (1)GCD存在于libdispatch.dylib这个库中,

iOS多线程技术—GCD的用法

iOS多线程技术—GCD的用法 一.主队列介绍 主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行. 提示:如果把任务放到主队列中进行处理,那么不论处理函数是异步的还是同步的都不会开启新的线程. 获取主队列的方式: 1 // 2 // YYViewController.m 3 // 12-GCD的基本使用(主队列) 4 // 5 // Created by 孔医己 on 14-6-25. 6 // Copyright (c) 2014

iOS 多线程技术1

iOS 多线程技术1 iOS 有三种多线程编程技术: NSThread NSOperation GCD 它们的抽象程度由低到高,越高的使用起来越简单. NSThread 显示调用 NSthread 类 类方法 + (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument; 实例方法 - (instancetype)initWithTarget:(id)target selecto

iOS多线程技术—NSOperation用法

iOS多线程技术—NSOperation用法 一.NSOperation简介 1.简单说明 NSOperation的作?:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个NSOperation对象中 (2)然后将NSOperation对象添加到NSOperationQueue中 (3)系统会?动将NSOperationQueue中的NSOperat

iOS多线程技术—多线程简单介绍

iOS多线程技术—多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcode,系统就会分别启动2个进程 通过“活动监视器”可以查看Mac系统中所开启的进程 2.什么是线程 1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程) 线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 比如使用酷狗播放音乐.使用迅雷下载电影,都需要在线程中执行 3.线程的