掌握GCD以及后台永久运行的代码 (使用GCD处理后台线程和UI线程的交互)
一个例子:
在iPhone上做一个下载网页的功能,就是:在iPhone上放一个按钮,单击按钮时,显示一个转动的圆圈,表示正在进行下载,下载完成后,将内容加载到界面上的一个文本控件上。
使用GCD前:
static NSOperationQueue *queue;
// 按钮的点击事件
-(void)someClick:(id)sender{
self.indicator.hidden = NO;
[self.indicator startAnimating];
queue = [NSOperationQueue alloc]init];
NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download) object:nil];
[queue addOperation:op];
}
-(void)download{
NSURL *url = [NSURL URLWithString:@"http://www.youdao.com"];
NSError *error;
NSString *data = [NSString stringWithContentOfURL:url encoding:NSUTF8StringEncoding error:&error];
if(data !=nil){
[self performSelectorOnMainThread:@selector(download_complexted:) withObject:data waitUntilDone:NO];
}else{
NSLog(@"%@",error);
}
}
-(void)download_complexted:(NSString *)data{
[self.indicator stopAnimating];
self.indicator.hidden = YES;
self.content.text = data;
}
使用GCD以前分成了三部分来写。
使用GCD后,以上三个方法可以放在一起:
self.indicator.hidden = NO;
[self.indicator startAnimating];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
NSURL *url = [NSURL URLWithString:@"http://www.youdao.com"];
NSError *error;
NSString *data = [NSString stringWithContentOfURL:url encoding:NSUTF8StringEncoding error:&error];
if(data !=nil){
dispatch_async(diapatch_get_main_queue(),^{
[self.indicator stopAnimating];
self.indicator.hidden = YES;
self.content.text = data;
});
}else{
NSLog(@"%@",error);
}
});
首先,看到代码变短了,变清楚了。
系统提供的dispatch方法
为了方便地使用GCD,苹果提供了一些方法方便我们将block放在主线程或后台线程执行,或者延后执行。使用的例子如下所示:
// 后台执行:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// something
}); // 主线程执行:
dispatch_async(dispatch_get_main_queue(), ^{
// something
}); // 一次性执行:
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// code to be executed once
}); // 延迟2秒执行:
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// code to be executed on the main queue after delay
});
dispatch_queue_t也可以自己定义,如要自定义queue,可以用dispatch_queue_create方法,示例如下:
// 自定义dispatch_queue_t
dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
dispatch_async(urls_queue, ^{
// your code
});
dispatch_release(urls_queue);
另外,GCD还有一些高级用法,例如让后台两个线程并行执行,然后等两个线程都结束后,再汇总执行结果。这个可以用dispatch_group_t、dispatch_group_async、dispatch_group_notify来实现,示例如下:
// 合并汇总结果
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行执行的线程一
});
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行执行的线程二
});
dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
// 汇总结果
});
修改block之外的变量,只需将__block引用在外部即可。
后台的运行:
在appdelegate.h
@property (assign,nonatomic)UIBackgroundTaskIdentifier backgroundUpdateTask;
在appdelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self beginBackgroundUpdateTask];
//在这里加上你需要长久运行的代码
[self endBackgroundUpdateTask];
}
-(void)beginBackgroundUpdateTask{
self.backgroundUpdateTask = [[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundUpdateTask];
}];
}
-(void)endBackgroundUpdateTask{
[[UIApplication sharedApplication]endBackgroundTask:self.backgroundUpdateTask];
self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}
掌握GCD以及后台永久运行的代码 (使用GCD处理后台线程和UI线程的交互)的更多相关文章
- springboot在阿里CentOS 7后台永久运行
查看Java进程可以使用 ps -ef|grep java 首次后台永久启动,会把日志输出到新建的log.file文件 nohup java -jar demo-0.0.1-SNAPSHOT.jar ...
- iOS-GCD处理后台线程和UI线程的交互
一个例子: 在iPhone上做一个下载网页的功能,就是:在iPhone上放一个按钮,单击按钮时,显示一个转动的圆圈,表示正在进行下载,下载完成后,将内容加载到界面上的一个文本控件上. 使用GCD前: ...
- C#中后台线程和UI线程的交互
在C#中,从Main()方法开始一个默认的线程,一般称之为主线程,如果在这个进行一些非常耗CPU的计算,那么UI界面就会被挂起而处于假死状态,也就是说无法和用户进行交互了,特别是要用类似进度条来实时显 ...
- Python--day02(编程语言、运行python代码、变量)
day01主要内容回顾 1.进制转换: 二进制: 1111 0101 1010 十六进制 f 5 a 2.内存分布:堆区 和 栈区 外来人只能访问栈区的数据 ...
- Android中UI线程与后台线程交互设计的5种方法
我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一 些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必 ...
- Android中后台线程如何与UI线程交互
我想关于这个话题已经有很多前辈讨论过了.今天算是一次学习总结吧. 在android的设计思想中,为了确保用户顺滑的操作体验.一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必须 ...
- Android中UI线程与后台线程交互设计的6种方法
在android的设计思想中,为了确保用户顺滑的操作体验.一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必须要重新开启 一个后台线程运行这些任务.然而,往往这些任务最终又会直 ...
- 【代码笔记】iOS-后台运行,可以选择在前台或后台或前后台
一,工程图. 二,代码. AppDelegate.h AppDelegate.m RootViewController.h #import <UIKit/UIKit.h> @interfa ...
- GCD之后台程序运行
点击Home键进入后台时进行计时,直到从新启动,超过三分钟启动手势 // // AppDelegate.m // GCDDown // // Created by City--Online on 15 ...
随机推荐
- android中实现view可以滑动的六种方法续篇(一)
承接上一篇,如果你没有读过前四章方法,可以点击下面的链接: http://www.cnblogs.com/fuly550871915/p/4985053.html 下面开始讲第五中方法. 五.利用Sc ...
- Asp.Net实现WebApi跨域 (非MVC)
目前WebApi在使用上大部分都是跟MVC组合的,而且使用起来也确实十分便利. 但有时候我们也需要在WebForm中使用WebApi,二者还是有一定区别的. 首先看下结构 ①ApiControlle ...
- 《MySQL技术内幕——SQL编程》读书笔记(二)——数据类型
对数据类型的选择将影响与数据库交互的应用程序的性能. 1.通常来说,如果一个页内可以存放尽可能多的行,那么数据库的性能就越好,因此选择一个正确的数据类型至关重要. 2.另一方面,如果在数据库中创建表时 ...
- 问题解决——使用CriticalSection后 0xXXXXXXXX处最可能的异常: 0xC0000005: 写入位置 0x00000014 时发生访问冲突
================声明===================== 本文原创,转载请保持文章的完整性(含本声明),并显要的著名作者和出处. 本文链接:http://blog.csdn.ne ...
- 问题解决——在结构体中使用set保存结构体数据
=====================声明========================== 本文原创,转载请明确的注明出处和作者,并保持文章的完整性(包括本声明部分). 本文链接:http:/ ...
- EasyUI DataGrid单选如何取消选中
EasyUI DataGrid在多选时,选中某行,可以取消:而在单选时,并不能取消选中某一行. 可以通过修改源码来完成. 在其源码中找到 opts.singleSelect==true 将代码做如下修 ...
- UVA 10827 Maximum sum on a torus (LA)
算法入门经典训练指南88页练习 ::这道题只要把原矩阵扩大4倍,那么其跟最大子矩阵的题目就很类似,把二维转化成一维,求最大的序列和,不过这个序列的长度不能超过n. 长度不能超过n? 那这道题又跟hdu ...
- yum 安装包的用法
最近刚爆出linux下glibc有重大漏洞,修复方案为升级glibc库 RHEL/CentOS下一键即可修复 : sudo yum update glibc .或者如果本地有rpm包 直接 rpm - ...
- runc的detach, console, tty等相关问题
runc 端解析: 1. runc/utils_linux.go func (r *runner) run(config *specs.Process) (int , error) 在该函数中第一次对 ...
- C++ 之 常量成员函数
类的常量成员函数 (const member function), 可以读取类的数据成员,但是不能修改. 1 声明 1.1 const 关键字 在参数列表后,加 const 关键字,声明为常量成员 ...