ios中得多线程技术主要使用3种:NSThreadNSOperationGCD

  一、NSThread: 最轻量级方法,但是不安全需要手动加锁,需要自己管理生命周期

    NSThread的使用方法有2种:   

// 第一种,需要start
1 NSThread *th1 = [[NSThread alloc] initWithTarget:self selector:@selector(btnClick) object:nil];
[th1 setName:@"线程1"];
[th1 start];
// 第二种
1 [NSThread detachNewThreadSelector:@selector(btnClick) toTarget:self withObject:nil];

  因为NSThread使用不安全,我们需要给它加锁(主要的实现代码):

 @property (nonatomic,assign) NSInteger fruits;
@property (nonatomic,strong) NSLock *lock;
- (void)viewDidLoad
{
[super viewDidLoad]; _lock = [[NSLock alloc] init];
_fruits = ;
} - (void)btnClick
{
@synchronized(_lock){ // 加锁 while (_fruits > ) { NSLog(@"当前线程为:%@ , 剩余票数为:%d",[NSThread currentThread], _fruits); _fruits--;
}
}
}

  二、GCD:(Grand Central Dispatch)是一种多核编码技术,用纯C语言编写。

  异步:具备开启线程的功能

  同步:不具备开启线程的功能

  并行队列:多个任务可以同时执行

  串行队列:执行完一个任务后再执行下一个任务

  下面来进行用代码说明:

 // 自定义异步方法
- (void)async:(dispatch_queue_t)queue
{
// 异步执行
dispatch_async(queue, ^{ NSLog(@"im1-%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{ NSLog(@"im2-%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{ NSLog(@"im3-%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{ NSLog(@"im4-%@",[NSThread currentThread]);
}); }
 // 自定义同步方法
- (void)sync:(dispatch_queue_t)queue
{
// 同步执行
dispatch_sync(queue, ^{ NSLog(@"im1-%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{ NSLog(@"im2-%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{ NSLog(@"im3-%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{ NSLog(@"im4-%@",[NSThread currentThread]);
}); }

调用异步执行方法

 // 创建一个全局并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); // 异步执行
[self async:queue];

最终的结果为:开启了四个线程,并且执行顺序是不定

 -- ::20.438 GCD[:1f07] im3-<NSThread: 0x7177ee0>{name = (null), num = }
-- ::20.432 GCD[:] im1-<NSThread: 0x7177d70>{name = (null), num = }
-- ::20.440 GCD[:] im4-<NSThread: 0x7178490>{name = (null), num = }
-- ::20.432 GCD[:1a03] im2-<NSThread: 0x75429f0>{name = (null), num = }
 // 创建一个全局串行队列
dispatch_queue_t queue = dispatch_queue_create("wys", NULL); // 异步执行
[self async:queue];

最终的结果为:开启了一个线程,执行顺序为从上往下依次执行

 -- ::19.415 GCD[:] im1-<NSThread: 0x71631a0>{name = (null), num = }
-- ::19.428 GCD[:] im2-<NSThread: 0x71631a0>{name = (null), num = }
-- ::19.437 GCD[:] im3-<NSThread: 0x71631a0>{name = (null), num = }
-- ::19.450 GCD[:] im4-<NSThread: 0x71631a0>{name = (null), num = }

调用主队列执行方法:

 // 创建主队列
dispatch_queue_t queue = dispatch_get_main_queue(); // 异步执行
[self async:queue];

最红的结果为:顺序执行并且不开启线程,在主线程中执行

 -- ::45.320 GCD[:c07] im1-<NSThread: 0x71560c0>{name = (null), num = }
-- ::45.333 GCD[:c07] im2-<NSThread: 0x71560c0>{name = (null), num = }
-- ::45.339 GCD[:c07] im3-<NSThread: 0x71560c0>{name = (null), num = }
-- ::45.347 GCD[:c07] im4-<NSThread: 0x71560c0>{name = (null), num = }
 // 创建主队列
dispatch_queue_t queue = dispatch_get_main_queue(); NSLog(@"start"); // 同步执行
[self sync:queue]; NSLog(@"end");

最终的结果为:执行到start就卡住了,不能往下执行

 -- ::12.856 GCD[:c07] start

调用同步执行方法:

 // 创建全局并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); // 同步执行
[self sync:queue];

最终的结果为:不开启线程,并且顺序执行,直接主线程执行

 -- ::27.448 GCD[:c07] im1-<NSThread: 0x71133c0>{name = (null), num = }
-- ::27.458 GCD[:c07] im2-<NSThread: 0x71133c0>{name = (null), num = }
-- ::27.468 GCD[:c07] im3-<NSThread: 0x71133c0>{name = (null), num = }
-- ::27.472 GCD[:c07] im4-<NSThread: 0x71133c0>{name = (null), num = }
 // 创建串行队列
dispatch_queue_t queue = dispatch_queue_create("wys", NULL); // 同步执行
[self sync:queue];

最终的结果为:不开启线程,并且顺序执行,直接主线程执行

 -- ::40.609 GCD[:c07] im1-<NSThread: 0x713e570>{name = (null), num = }
-- ::40.621 GCD[:c07] im2-<NSThread: 0x713e570>{name = (null), num = }
-- ::40.626 GCD[:c07] im3-<NSThread: 0x713e570>{name = (null), num = }
-- ::40.634 GCD[:c07] im4-<NSThread: 0x713e570>{name = (null), num = }

多线程之间的通信:UI界面的更新一定要在主线程中执行

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{ // 全局并行队列异步执行

         NSLog(@"全局并行队列异步执行 - %@",[NSThread currentThread]);

         // 获取网络图片数据
NSString *str = @"https://ss0.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3384245408,2851245305&fm=21&gp=0.jpg";
NSURL *url = [NSURL URLWithString:str]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; dispatch_async(dispatch_get_main_queue(), ^{ // 主线程异步执行 NSLog(@"主线程异步执行 - %@",[NSThread currentThread]); // 更新界面
[_im1 setImage:image];
}); });

最终的结果为:

-- ::08.513 GCD[:] 全局并行队列异步执行 -<NSThread: 0x754c530>{name = (null), num = }
-- ::10.657 GCD[:c07] 主线程异步执行 -<NSThread: 0x7132c80>{name = (null), num = }

利用多线程来实现延时执行:

1、利用GCD

 double delayInSeconds = 2.0; // 延时时长
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ // 在主线程中执行 NSLog(@"%@",[NSThread currentThread]); // 更新界面
[_im1 setImage:image]; });

2、利用此方法,performSelector为你要调用的方法,withObject为你要传得值,afterDelay为延时时长

 [self performSelector:@selector(downLoad) withObject:nil afterDelay:0.5f];

队列组:

 dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); dispatch_group_async(group, queue, ^{ // 代码1
}); dispatch_group_async(group, queue, ^{ // 代码2
}); dispatch_group_notify(group, queue, ^{ // 执行完代码1和代码2后,再执行此方法
});

  

  三、NSOperation:基于GCD,能控制最大并发线程数,主要有2个类:NSInvocationOperation和NSBlockOperation

  其步骤为: 创建队列、添加操作、将操作添加到队列

  A、NSInvocationOperation:

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSInvocationOperation *invo = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(buy) object:nil]; [queue addOperation:invo]; } - (void)buy
{
NSLog(@"%@",[NSThread currentThread]);
}

最后的结果为:开启了一个线程

 -- ::54.060 op1[:1e07] <NSThread: 0x71a6de0>{name = (null), num = }

  

  B、NSBlockOperation

 NSOperationQueue *queue = [[NSOperationQueue alloc] init];

     NSBlockOperation *b1 = [NSBlockOperation blockOperationWithBlock:^{

         NSLog(@"111--%@",[NSThread currentThread]);
}];
NSBlockOperation *b2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"222--%@",[NSThread currentThread]);
}];
NSBlockOperation *b3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"333--%@",[NSThread currentThread]);
}]; [queue addOperation:b1];
[queue addOperation:b2];
[queue addOperation:b3];

最后的结果为:开启了三个线程,自动异步执行

 -- ::59.897 op1[:1a03] --<NSThread: 0x7544fa0>{name = (null), num = }
-- ::59.901 op1[:] --<NSThread: 0x71506f0>{name = (null), num = }
-- ::59.902 op1[:] --<NSThread: 0x7545e60>{name = (null), num = }

设置依赖:

 // 设置依赖 ,b2依赖b1,b3依赖b2,所以执行顺序为,b1->b2->b3
[b2 addDependency:b1];
[b3 addDependency:b2];

设置队列的最大并发数量

 // 设置最大并发(最多同时并发执行3个任务)
queue.maxConcurrentOperationCount = ;

  C、主队列

 NSOperationQueue *queue = [[NSOperationQueue alloc] init];

     [queue addOperationWithBlock:^{

           NSLog(@"-------%@",[NSThread currentThread]);

                // 获取网络图片数据
NSString *str = @"https://ss0.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3384245408,2851245305&fm=21&gp=0.jpg";
NSURL *url = [NSURL URLWithString:str]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; [[NSOperationQueue mainQueue] addOperationWithBlock:^{ // 主队列 NSLog(@"******%@",[NSThread currentThread]); // 更新界面
[_im1 setImage:image];
}];
}];

最后的结果为:

 -- ::16.077 op1[:1c03] -------<NSThread: 0x71613e0>{name = (null), num = }
-- ::17.593 op1[:c07] ******<NSThread: 0x7134fa0>{name = (null), num = } // 主队列

iOS 多线程(NSThread、GCD、NSOperation)的更多相关文章

  1. iOS多线程 NSThread/GCD/NSOperationQueue

    无论是GCD,NSOperationQueue或是NSThread, 都没有线程安全 在需要同步的时候需要使用NSLock或者它的子类进行加锁同步 "] UTF8String], DISPA ...

  2. [iOS]多线程和GCD

    新博客wossoneri.com 进程和线程 进程 是指在系统中正在运行的一个应用程序. 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 比如同时打开QQ.Xcode,系统就会分别 ...

  3. ios多线程NSThread

    1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue ...

  4. iOS 多线程学习笔记 —— NSOperation

    本文复制.参考自文章:iOS多线程编程之NSOperation和NSOperationQueue的使用 ,主要为了加强个人对知识的理解和记忆,不做他用.原作者声明: 著作权声明:本文由http://b ...

  5. 多线程 NSThread GCD

    ios多线程实现种类 NSThread NSOperationQueue NSObject GCD *************** 1.NSThread //线程 第一种 NSThread *thre ...

  6. iOS多线程开发之NSOperation - 快上车,没时间解释了!

    一.什么是NSOperation? NSOperation是苹果提供的一套多线程解决方案.实际上NSOperation是基于GCD更高一层的封装,但是比GCD更加的面向对象.代码可读性更高.可控性更强 ...

  7. iOS多线程开发之NSOperation

    一.什么是NSOperation? NSOperation是苹果提供的一套多线程解决方案.实际上NSOperation是基于GCD更高一层的封装,但是比GCD更加的面向对象.代码可读性更高.可控性更强 ...

  8. [转] iOS多线程编程之NSOperation和NSOperationQueue的使用

    <iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是用定义好 ...

  9. iOS多线程编程之NSOperation和NSOperationQueue的使用

    前一篇 <iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是 ...

  10. iOS多线程NSThread和GCD

    在iOS中啊  其实有多种方法实现多线程 这里只记录两个比较常用的  或者说我比较常用的 一个就是BSThread 另一个就是一听名字就比较霸气的妇孺皆知的GCD 先说一下NSThread吧 这个方式 ...

随机推荐

  1. 关于cookies,sessionStorage和localStorage的区别

    如果我说得啰嗦了,请麻烦提醒我一下~~ 面试的时候说: 首先这三个可以在浏览器端按下F12,在Application可以查看到. 如下图: cookies: sessionStorage: sessi ...

  2. 前端实现Tab切换栏

    tab切换,所需的 UI 只有两组元素 - Header 和 Tab,下面介绍几种不同的实现方法和他们的优缺点 本文主要说一些 CSS 的实现方法.最好的方法是 第四种 => label + i ...

  3. JavaScript高级程序设计第三版-读书笔记(1-3章)

    这是我第一次用markdown,也是我第一次在网上记录我自己的学习过程. 第一章 JavaScript主要由以下三个不同的部分构成 ECMAScript   提供核心语言功能 DOM     提供访问 ...

  4. 1093 Count PAT's(25 分)

    The string APPAPT contains two PAT's as substrings. The first one is formed by the 2nd, the 4th, and ...

  5. jquery——解决鼠标移入移出导致盒子不停移动的bug

    使用mouseover().mouseout()时会出现这样一种情况,鼠标快速多次移入移出后这个盒子会在鼠标不动后继续运动 代码如下: <!DOCTYPE html> <html l ...

  6. 配置HEXO

    软件介绍 Hexo 是一个快速.简洁且高效的博客框架.Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页. 使用版本和操作系统 官网最新版 Windo ...

  7. arch搭建SVN服务器

    一.安装 Install the package Install subversion from the official repositories. Create a repository Crea ...

  8. PHP session变量的销毁

    1.何为session? 相当于一个客户端(可以是浏览器.app.ftp等其他,而且同一个浏览器多开几个又算是不同的客户端)对服务器的一个访问,这个期间服务器为此建立一个唯一的标示(session_i ...

  9. Mybatis-Plus使用全解

    前言 之前写了<SpringBoot | 第九章:Mybatis-plus的集成和使用>一文,只是简单的使用条件构造器列举了一些通用的CURD操作.本人也想写一篇通用的关于mybatis- ...

  10. JavaFX上手--第1天

    1.第一个JavaFX Application JavaFX 使用Java来制作可视化图形,可以做动画和3D效果,JavaFX从JDK中直接使用. package application; impor ...