iOS中的多线程一般使用场景

在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]; // 恢复队列中的所有任务
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247144.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iOS中如何优化Cell中图片的下载性能

在iOS开发中使用最为常见的是UITableView&#xff0c;其中UITabelViewCell中下载图片&#xff0c;会影响用户下拉刷新UI,导致卡顿&#xff0c;用户体验不好&#xff0c;在这篇blog中&#xff0c;我将以一个例子来说明如何优化UITableView下载图片 1.使用懒加载方式&#xff0c…

【Yoshua Bengio 亲自解答】机器学习 81 个问题及答案(最全收录)

本文转自&#xff1a;http://mp.weixin.qq.com/s?__bizMzI3MTA0MTk1MA&mid401958262&idx1&sn707f228cf5779a31f0933af903516ba6&scene1&srcid0121zzdeFPtgoRoEviZ3LZDG#rd 译者&#xff1a;张巨岩 王婉婷 李宏菲 戴秋池 这是 Quora 的最新节目&#xf…

Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析

Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明&#xff1a;Java生鲜电商平台中&#xff0c;由于服务进行了拆分&#xff0c;很多的业务服务导致了请求的网络延迟与性能消耗&#xff0c;对应的这些问题&#xff0c;我们应该如何进行网络请求的优化与…

XCode7 创建framework

1.新建一个静态库工程. file→ new→ project, 弹出框中选择iOS→ framework & library中的cocoa touch static library.点击Next,输入product name: TestFramework, 点击Next→ 点击Create. 2.删除向导所生成工程中的Target. 点击工程名→ 点击TARGETS → 右键Delete. …

基础js逆向练习-登录密码破解(js逆向)

练习平台&#xff1a;逆向账号密码 https://login1.scrape.center/ 直接打开平台&#xff0c;输入密码账号&#xff0c;抓包找到加密的参数携带的位置&#xff0c;这边我们找到的是一个叫token的加密参数&#xff0c;这个参数的携带是一个密文 我们首先考虑一下搜索这个加密的…

python之socket

socket套接字 什么叫socket socket是处于应用层与传输层之间的抽象层,他是一组操作起来非常简单的接口(接受数据)此接口接受数据之后,交由操作系统.socket在python中就是一个模块. socket两个分类 基于文件类型的套接字家族 套接字家族的名字&#xff1a;AF_UNIX unix一切皆文件…

iOS----JSON解析

在iOS开发中与服务器进行数据交互操作&#xff0c;操作过程中使用最为常见的格式为JSON与XML,其中JSON较为清量,因此本篇blog就讲解一下如何在iOS中进行JSON解析。 1.建立HTTP请求 &#xff08;1&#xff09;创建URL NSString *URLStr [NSString stringWithFormat:”http:/…

VS中每次改代码后运行程序不更新,只有重新编译才生效。

解决方法&#xff1a;将项目移除解决方案&#xff0c;再重新添加进来&#xff0c;即添加->现有项目->选择.vcxproj文件&#xff0c;即可解决。 转载于:https://www.cnblogs.com/Gregg/p/11358711.html

socket补充:通信循环、链接循环、远程操作及黏包现象

socket补充&#xff1a;通信循环、链接循环、远程操作及黏包现象 socket通信循环 server端&#xff1a; import socketphone socket.socket(socket.AF_INET,socket.SOCK_STREAM)phone.bind((127.0.0.1,8080))phone.listen(5)conn, client_addr phone.accept() print(conn, cl…

PCA的原理及MATLAB实现

相关文章 PCA的原理及MATLAB实现 UFLDL教程&#xff1a;Exercise:PCA in 2D & PCA and Whitening python-A comparison of various Robust PCA implementations &#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&a…

Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理

Java生鲜电商平台-SpringCloud微服务架构中核心要点和实现原理 说明&#xff1a;Java生鲜电商平台中&#xff0c;我们将进一步理解微服务架构的核心要点和实现原理&#xff0c;为读者的实践提供微服务的设计模式&#xff0c;以期让微服务在读者正在工作的项目中起到积极的作用。…

iOS中下载小文件

在iOS中通过网络下载小文件比如小型图片等资源&#xff0c;一般在子线程中将数据完全下载完毕&#xff0c;然后在调用block将下载的数据整个部分返回&#xff0c;或者采用同步返回下载数据。 一般采用以下两种方式&#xff1a; &#xff08;1&#xff09;使用GCD将下载操作放…

iOS下载大文件原理解析一

iOS中下载大型文件&#xff0c;需要考虑到占用内存的大小与下载速度&#xff08;使用多线程&#xff09;&#xff0c;因此本文首先介绍一个原理性下载文件的DEMO。 在下载大型文件中&#xff0c;需要知道下载的进度因此需要使用代理模式&#xff0c;不断的回调下载进度。 - (…

recv原理、高阶版黏包解决方案、基于UDP的socket通信

recv原理、高阶版黏包解决方案、基于UDP的socket通信 recv原理 源码解释&#xff1a; Receive up to buffersize bytes from the socket. 接收来自socket缓冲区的字节数据&#xff0c; For the optional flags argument, see the Unix manual. 对于这些设置的参数&#xff0c;可…

iOS中下载大型文件的原理解析二

在iOS中下载大型文件&#xff0c;需要使用NSURLConnection 的代理方法&#xff1a; (void)touchesBegan:(NSSet)touches withEvent:(UIEvent *)event { NSURL *url [NSURL URLWithString:”http://d.3987.com/fengj_141112/007.jpg“]; NSURLRequest *request [NSURLReque…

ASP.NET Core Web 应用程序开发期间部署到IIS自定义主机域名并附加到进程调试

想必大家之前在进行ASP.NET Web 应用程序开发期间都有用到过将我们的网站部署到IIS自定义主机域名并附加到进程进行调试。 那我们的ASP.NET Core Web 应用程序又是如何部署到我们的IIS上面进行调试的呢&#xff0c;接下来我们来简单介绍下&#xff1a; 一、安装IIS所需的Host扩…

iOS下载大型文件原理解析三

在下载大型文件过程中是可以取消下载的 - (IBAction)download:(UIButton *)sender { // 状态取反 sender.selected !sender.isSelected; // 断点续传 // 断点下载if (sender.selected) { // 继续&#xff08;开始&#xff09;下载// 1.URLNSURL *url [NSURL URLWithStrin…

HTML文件上传与下载

文件下载 传统的文件下载有两种方法&#xff1a; 使用<a/>标签&#xff0c;href属性直接连接到服务器的文件路径window.location.href"url"这两种方法效果一样。但有个很大的问题&#xff0c;如果下载出现异常&#xff08;连接路径失效、文件不存在、网络问题等…

NSURLSession的应用

iOS7以后发布了NSURLSession用来替换NSURLConnection&#xff0c;NSURLSession使用方式有以下两种&#xff1a; 1.block方式 &#xff08;1&#xff09;创建的步骤 获取单例会话对象 创建URL对象 隐含创建request 创建NSURLSessionDataTask // 1.获取会话对象 NSURLSess…