在IOS开发中为提高程序的运行效率会将比较耗时的操作放在子线程中执行,iOS系统进程默认启动一个主线程,用来响应用户的手势操作以及UI刷新,因此主线程又叫做UI线程。
前面的Blog说明了NSThread以及GCD处理并发线程以及线程安全(线程锁@synchronized(){}),线程通信(从子线程向主线程传递值,刷新界面),接下来讨论线程的延迟与执行的单一化(唯一执行一次)。
1.延迟
(1)最简单粗暴的方法是对线程本身执行挂起操作
[NSThread sleepForTimeInterval:]
另外使用隐式创建开启线程的方法
self performSelector:withObject:afterDelay:
(2)使用GCD处理延迟操作(线程,任务)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
<#code to be executed after a specified delay#>
});
2.只执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
<#code to be executed once#>
});
3.为了方便管理任务队列中的任务,GCD特用分组的方式来管理
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, queue, ^{
});
dispatch_group_notify(group, queue, ^{});
4.NSOperation与NSOperationQueue
为了对线程的操作更加的面向对象,APPLE对GCD进行了封装,特将任务—->封装成NSOperation
队列——>封装成NSOperationQueue
(1)NSOperation有两个子类NSInvocationOperation以及NSBlockOperation
NSInvocationOperation的创建方法如下:
// 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 创建操作
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
// operation直接调用start,是同步执行(在当前线程执行操作)
// [operation start];

// 添加操作到队列中,会自动异步执行
[queue addOperation:operation];

(2)NSBlockOperation的创建方法:
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@”—下载图片—-11—%@”, [NSThread currentThread]);
}];

[operation1 addExecutionBlock:^{NSLog(@"---下载图片----12---%@", [NSThread currentThread]);
}];NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"---下载图片----2---%@", [NSThread currentThread]);
}];NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"---下载图片----3---%@", [NSThread currentThread]);
}];NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"---下载图片----4---%@", [NSThread currentThread]);
}];// 1.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];// 主队列

// NSOperationQueue *queue = [NSOperationQueue mainQueue];

// 2.添加操作到队列中(自动异步执行)
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];

其中NSOperation类可以添加执行代码块:addExecutionBlock
【NSOperationQueue mainQueue】是获取主队列,其实底层相当于dispatch_get_mainQueue()

NSBlockOperation *operation = [[NSBlockOperation alloc] init];[operation addExecutionBlock:^{NSLog(@"---下载图片----1---%@", [NSThread currentThread]);
}];[operation addExecutionBlock:^{NSLog(@"---下载图片----2---%@", [NSThread currentThread]);
}];[operation addExecutionBlock:^{NSLog(@"---下载图片----3---%@", [NSThread currentThread]);
}];[operation start];// 任务数量 > 1,才会开始异步执行

5.线程的通信
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// 1.异步下载图片
NSURL *url = [NSURL URLWithString:@”http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg“];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];

    // 2.回到主线程,显示图片

// [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
// dispatch_async(dispatch_get_main_queue(), ^{
//
// });
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = image;
}];
}];
控制Operation之间的运行顺序可以通过添加依赖来实现
- (void)dependency
{
/**
假设有A、B、C三个操作,要求:
1. 3个操作都异步执行
2. 操作C依赖于操作B
3. 操作B依赖于操作A
*/

// 1.创建一个队列(非主队列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];// 2.创建3个操作
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"A1---%@", [NSThread currentThread]);
}];
//    [operationA addExecutionBlock:^{
//        NSLog(@"A2---%@", [NSThread currentThread]);
//    }];
//
//    [operationA setCompletionBlock:^{
//        NSLog(@"AAAAA---%@", [NSThread currentThread]);
//    }];NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"B---%@", [NSThread currentThread]);
}];
NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"C---%@", [NSThread currentThread]);
}];// 设置依赖
[operationB addDependency:operationA];
[operationC addDependency:operationB];// 3.添加操作到队列中(自动异步执行任务)
[queue addOperation:operationC];
[queue addOperation:operationA];
[queue addOperation:operationB];

}

为了达到优化app性能的需求,有时候是需要控制并发线程的数目以及队列中的线程的运行状态
- (void)maxCount
{
// 1.创建一个队列(非主队列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 2.设置最大并发(最多同时并发执行3个任务)
queue.maxConcurrentOperationCount = 3;// 3.添加操作到队列中(自动异步执行任务,并发)
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"下载图片1---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"下载图片2---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"下载图片3---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"下载图片4---%@", [NSThread currentThread]);
}];
NSInvocationOperation *operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];
[queue addOperation:operation5];
[queue addOperationWithBlock:^{NSLog(@"下载图片5---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{NSLog(@"下载图片6---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{NSLog(@"下载图片7---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{NSLog(@"下载图片8---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{NSLog(@"下载图片9---%@", [NSThread currentThread]);
}];[queue cancelAllOperations];

}

  • (void)didReceiveMemoryWarning
    {
    [super didReceiveMemoryWarning];

// [queue cancelAllOperations]; // 取消队列中的所有任务(不可恢复)
}

  • (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
    // [queue setSuspended:YES]; // 暂停队列中的所有任务
    }

  • (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {
    // [queue setSuspended:NO]; // 恢复队列中的所有任务
    }

iOS中的多线程一般使用场景相关推荐

  1. iOS中的多线程 NSOperation

    在ios中,使用多线程有三种方式,分别是:NSThread.NSOperation和NSOperationQueue.GCD,在本节,主要讲解一下NSOperation的使用. NSOperation ...

  2. iOS中实现多线程的技术方案

    pthread 实现多线程操作 代码实现: void * run(void *param) {for (NSInteger i = 0; i < 1000; i++) {NSLog(@" ...

  3. iOS 开发中的多线程

    线程.进程 什么是线程.进程   有的人说进程就像是人的脑袋,线程就是脑袋上的头发~~.其实这么比方不算错,但是更简单的来说,用迅雷下载文件,迅雷这个程序就是一个进程,下载的文件就是一个线程,同时下载 ...

  4. iOS中的异步和多线程概况

    一.异步 (1)当一个异步过程调用发出后,调用者不能立刻得到结果.实际处理这个调用的部件在完成后,通过状态.通知和回调来通知调用者.比如iOS类库中的NSURLConnectioin中使用代理的方式就 ...

  5. iOS四种多线程(swift和oc)

    在这篇文章中,我将为你整理一下 iOS 开发中几种多线程方案,以及其使用方法和注意事项.当然也会给出几种多线程的案例,在实际使用中感受它们的区别.还有一点需要说明的是,这篇文章将会使用 Swift 和 ...

  6. c语言block内部的实现原理,iOS中block变量捕获原理详析

    Block概述 Block它是C语言级别和运行时方面的一个特征.Block封装了一段代码逻辑,也用{}括起,和标准C语言中的函数/函数指针很相似,此外就是blokc能够对定义环境中的变量可以引用到.这 ...

  7. 关于iOS中图片处理的小结

    iOS实现图形编程可以使用三种API(UIKIT.Core Graphics.OpenGL ES及GLKit). 这些api包含的绘制操作都在一个图形环境中进行绘制.一个图形环境包含绘制参数和所有的绘 ...

  8. 【iOS】—— iOS中的相关锁

    文章目录 自旋锁 1.OSSpinLock 2.os_unfair_lock 3.atomic 互斥锁 pthread_mutex @synchronized objc_sync_enter objc ...

  9. iOS开发-10.多线程

    1.iOS中的常见多线程方案 a) NSThread / GCD / NSOperation底层都是pthreadb) NSThread开启线程方式1) 动态实例化 NSThread *thread ...

最新文章

  1. Python--数据存储:pickle模块的使用讲解
  2. Webservice开发流程
  3. java 资深工程师必备技能
  4. 你需要学好知识图谱----用AI技术连接世界
  5. LeetCode 563. Binary Tree Tilt
  6. Matter-JS Composite.add 符合材料添加约束
  7. C#中你可能不知道的8件事(zz)
  8. cmos和ttl_CMOS与TTL电路的详细对比区别
  9. python request模块下载_python中的Requests模块
  10. 论文翻译:Few-Shot Object Detection with Attention-RPN and Multi-Relation Detector
  11. 电脑安装系统时提示“找不到硬盘”如何解决
  12. 根据显示屏分辨率调试html 样式
  13. 思科 计算机网络 第十章测试考试答案
  14. 原生js或者jquery获取父级元素/同级元素/下级元素
  15. 过程计算机系统 pcs,炼钢AOD炉过程计算机系统设计与实现-软件工程专业毕业论文.docx...
  16. 英语语法汇总(8.动词)
  17. QT入门之QMainWindow
  18. Python 基础篇(三)--初步编程总结,各种常识
  19. java -jar xx.jar是如何运行的
  20. matlab仿真时三相电流设置,三相输入电流波形与三相整流MATLAB仿真

热门文章

  1. c语言排序系统代码怎么写,排序概述(c语言)(示例代码)
  2. codeforces 153d(日期转换)特殊题目
  3. 深度学习(32)随机梯度下降十: 手写数字识别问题(层)
  4. 数学--数论-- HDU 2601 An easy problem(约束和)
  5. HDU 1159.Common Subsequence【动态规划DP】
  6. kafka自动提交offset失败:Auto offset commit failed
  7. Python+Opencv实现自动化阅卷
  8. 集合计数 二项式反演_对计数数据使用负二项式
  9. 唐宇迪机器学习课程数据集_最受欢迎的数据科学和机器学习课程-2020年8月
  10. 为什么基于数字的技术公司进行机器人研究