iOS UI异步更新:dispatch_async 与 dispatch_get_global_queue 的使用方法
GCD (Grand Central Dispatch) 是Apple公司开发的一种技术,它旨在优化多核环境中的并发操作并取代传统多线程的编程模式。 在Mac OS X 10.6和IOS 4.0之后开始支持GCD。
使用GCD的一个理由就是方便。回想一下以前的多线程编程,我们会把异步调用的代码放到另外的一个函数中,并通过NSThread开启新线程来启动这段代码。 这种跳来跳去的流程对于复杂的逻辑简直就是一场灾难。更糟糕的是,调用线程时的环境对异步代码是不可见的,如果我们需要当时的临时变量的话只有两个选择: 保存到类成员变量中或者作为参数传递过去。前者会造成很多莫名奇妙的无关类成员,而后者的功能过于有限。
-(void) referCurrencyRate:(UIButton *)btn{
activity.hidden=NO;
[activity startAnimating];
// may be get param
//
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//do lost large time works
NSString *rate= [NetConnect GetCurrentcyRateTester:@""];
dispatch_async(dispatch_get_main_queue(), ^{
//继续UI 更新等
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:rate
delegate:nil
cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[alert show];
[activity stopAnimating];
[activity setHidesWhenStopped:YES];
});
});
// [NSTimer scheduledTimerWithTimeInterval:5.5 target:self selector:@selector(hid) userInfo:nil repeats:NO];
}
在上面的代码中,出现了一种奇怪的格式:
^{code...}
解释一下,当一段代码被花括号包裹并在开头放置上尖号时,我们称之为块(block)。如果你学过C语言的话(实际上,block正是apple对C的一个扩展), 你可以认为这是一个增强型的函数指针。它不仅可以当做一个变量来回传递,还可以引用本身环境之外的变量(如上面代码中的parameter)。 更进一步地说,它是apple的C扩展中闭包的实现。在block里引用的对象会自动被retain,因此你也不必担心内存的问题。
另外涉及到了三个函数
void dispatch_async(
dispatch_queue_t queue,
dispatch_block_t block);
dispatch_queue_t dispatch_get_global_queue(
long priority,
unsigned long flags);
dispatch_get_main_queue();
dispatch_async 函数会将传入的block块放入指定的queue里运行。这个函数是异步的,这就意味着它会立即返回而不管block是否运行结束。因此,我们可以在block里运行各种耗时的操作(如网络请求) 而同时不会阻塞UI线程。
dispatch_get_global_queue 会获取一个全局队列,我们姑且理解为系统为我们开启的一些全局线程。我们用priority指定队列的优先级,而flag作为保留字段备用(一般为0)。
dispatch_get_main_queue 会返回主队列,也就是UI队列。它一般用于在其它队列中异步完成了一些工作后,需要在UI队列中更新界面(比如上面代码中的[self updateUIWithResult:result])的情况。
好的,知道这些特性之后,我们可以这样理解上面的代码:利用parameter变量异步地发起一个网络请求,并在请求之后更新UI线程。
这种需求很常见,诸如页面数据刷新等,基本IOSAPP这种展示的类的东西,这种用法常见。之前,我做指示器的使用都是定时器,现在都改成这种了。
定时器也可以实现这种方法,但是这不是定时器该做的事。
iOS UI异步更新:dispatch_async 与 dispatch_get_global_queue 的使用方法的更多相关文章
- dispatch_async 与 dispatch_get_global_queue 的使用方法
GCD (Grand Central Dispatch) 是Apple公司开发的一种技术,它旨在优化多核环境中的并发操作并取代传统多线程的编程模式. 在Mac OS X 10.6和IOS 4.0之后开 ...
- 使用AsyncTask异步更新UI界面及原理分析
概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...
- Android异步更新UI的四种方式
Android异步更新UI的四种方式 2015-09-06 09:23 segmentfault 字号:T | T 大家都知道由于性能要求,android要求只能在UI线程中更新UI,要想在其他线程中 ...
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍 ...
- handler机制和异步更新UI页面
Android 提供了Handler和Looper来满足线程之间的通行,Handler是先进先出原则,Looper类用来管理特定线程内对象之间的消息互换,也可以使用Runnable来完成页面异步更新 ...
- Android 通过广播来异步更新UI
之前的项目里要做一个异步更新UI的功能,可是结果出现了ANR,所以想写个demo来測试究竟是哪个地方出现了问题,结果发现原来的思路是没有问题,郁闷~~ 如今这个demo 就是模拟项目里面 的步骤 1. ...
- Winform实现多线程异步更新UI(进度及状态信息)
引言 在进行Winform程序开发需要进行大量的数据的读写操作的时候,往往会需要一定的时间,然在这个时间段里面,界面ui得不到更新,导致在用户看来界面处于假死的状态,造成了不好的用户体验.所以在大量数 ...
- Android异步处理系列文章四篇之二 使用AsyncTask异步更新UI界面
Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...
- Android异步处理系列文章四篇之一使用Thread+Handler实现非UI线程更新UI界面
目录: Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+L ...
随机推荐
- I.MX6 MAC Address hacking
/************************************************************************** * I.MX6 MAC Address hack ...
- CF838D Airplane Arrangement
题目描述:https://www.luogu.org/problemnew/show/CF838D(有翻译) (为什么博客园把我刚写的给吞了……orz) 这题当初看的十分懵逼,不过听了肖大佬的做法还是 ...
- 【旧文章搬运】分析了一下360安全卫士的HOOK(二)——架构与实现
原文发表于百度空间及看雪论坛,2009-10-14 看雪论坛地址:https://bbs.pediy.com/thread-99460.htm 刚发这篇文章的时候,因为内容涉及360的核心产品,文章被 ...
- emacs在org-mode时输出pdf时,只输出为链接
这个找到问题了,写错格式了,输出pdf中要内嵌图像,格式要写成[[file:/home/xxx/yyy.jpg]],不能写成file:/home/xxx/yyy.jpg或者[[file:/home/x ...
- 20170406-ms
Interval 间隔 revoke v撤销 alert adj 警觉的 n警报
- Androidstudio中添加jar包的方法
在Androidstudio中添加一个jar包进去,怎么添加? 以下纯个人使用Androidstudio过程中的经验积累,要是有不足,望提出建议. 方法一: 先点击Androidstudio中的Pro ...
- 51nod1014【暴力】
直接暴力1e6就好了 #include <bits/stdc++.h> using namespace std; typedef long long LL; int main() { LL ...
- UVALive 6833【模拟】
题意: 算从左往右的值,先乘后加的值,数的范围<=9= =,然后根据满足的条件输出字符. 思路: 从左往右就是直接来了,先做乘法就是乘法两边的数字靠向右边那个,且左边那个为0,然后所有值一加就好 ...
- hdoj1150(最小点覆盖)
题意: 两台机器,A台机器有N种模式,B台机器有M种不同的模式,初始模式都是0 以及K个需要运行的任务(i,x,y),在A台机器是x模式,在B台机器是y模式. 请合理为每个任务安排一台机器并合理安排顺 ...
- 洛谷P4867 Gty的二逼妹子序列(莫队+树状数组)
传送门 本来打算用主席树 然后发现没办法维护颜色数 于是用了莫队加树状数组 然后竟然A了…… //minamoto #include<iostream> #include<cstdi ...