IOS 多线程编程指南_GCD
来源:互联网 发布:淘宝潮男店铺粉丝排行 编辑:程序博客网 时间:2024/05/16 05:29
- dispatch_apply
简介:功能:把一项任务提交到队列中多次执行,具体是并行执行还是串行执行由队列本身决定.注意,dispatch_apply不会立刻返回,在执行完毕后才会返回,是同步的调用。
iterations 执行的次数
queue 提交到的队列
block 执行的任务
dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));
应用举例1>
比如我有一个数组,存储了一系列对象,初始化的时候,这些对象都要调用一次某函数来进行相关的计算。这些计算相互没有影响。这时,我们就可以用dispatch_apply来使用异步队列来初始化.这里把这种情况进行简化
NSMutableArray* muarray = [@[@"hello",@"hellolcg",@"goodbay lms"]mutableCopy]; dispatch_apply(3,dispatch_get_global_queue(0,0),^(size_t time){ NSLog(@"str=%@",muarray[time]); }); NSLog(@"Dispatch_after in global queue is over");
dispatch_get_global_queue 为全局的并发队列,执行顺序是不确定的,size_t time 的数值必须小于数组数量,否则会越界崩溃
dispath_apply是同步执行的,所以只有数组打印完之后才会执行
NSLog(@”Dispatch_after in global queue is over”);
由于同步执行会导致线程阻塞,所以做了以下改进
dispatch_async(dispatch_get_global_queue(0, 0), ^{ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"ssssssssssssss"); }); NSLog(@"Dispatch_after in global queue is over"); });
应用举例2>
- (IBAction)clicked:(id)sender{ // 控制代码块执行5次 dispatch_apply(5 , dispatch_get_global_queue(0, 0) // time形参代表当前正在执行第几次 , ^(size_t time) { NSLog(@"===执行【%lu】次===%@" , time , [NSThread currentThread]); });}
这里并发执行第五次打印,但不一定是并发了五个线程,可能是由系统资源确定的
2.dispatch_after
功能:延迟一段时间把一项任务提交到队列中执行,返回之后就不能取消
常用来在在主队列上延迟执行一项任务
函数原型
dispatch_after(dispatch_time_t when,
dispatch_queue_t queue,
dispatch_block_t block);
参数
when 过了多久执行的时间间隔
queue 提交到的队列
block 执行的任务
例如:可以利用dispatch_after写一个自己用的Delay函数,delay一段时间在主线程上执行一段代码
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"ssssssssssssss"); });
应用举例1>
比如,当用户的应用不满足某些我们App需要的条件时候(例如,我们的App需要蓝牙打开),然后在APP启动的时候测到蓝牙Off后,应当给用户一个提示。在view载入完成后,延迟给用户一个提示,也可以给这个提示添加一些动画,要比view在载入完成直接显示提示要有好的多。
举例
在viewLoad后,延迟1s,提示一个alertview
class ViewController: UIViewController{ func hwcDelay(delay:Double, closure:()->()) { dispatch_after( dispatch_time( DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)) ), dispatch_get_main_queue(), closure)} override func viewDidLoad(){ super.viewDidLoad() hwcDelay(1.0){ var alertview = UIAlertView(title:"Dispatch_after",message:"Message",delegate:self,cancelButtonTitle:"OK") alertview.show() } } override func didReceiveMemoryWarning(){ super.didReceiveMemoryWarning() } }
3.dispatch_once
功能:保证在APP运行期间,block中的代码只执行一次
在生成单例的经常使用
当然也可以在多线程环境下,保证一段代码只执行一次。
+ (instancetype)sharedInstance { static id sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [[self alloc] init]; }); return sharedInstance;}
单例或许你不太明白,下面写一个按钮,无论点击多少次
NSLog输出只会执行一次
- (IBAction)clicked:(id)sender{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"==执行代码块=="); // 线程暂停3秒 [NSThread sleepForTimeInterval:3]; });}
4.dispatch_sync()
同步添加操作。他是等待添加进队列里面的操作完成之后再继续执行
- (IBAction)clicked:(id)sender{ // 以同步方式先后提交2个代码块 dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) , ^(void){ for (int i = 0 ; i < 100; i ++) { NSLog(@"%@=====%d" , [NSThread currentThread] , i); [NSThread sleepForTimeInterval:0.1]; } }); // 必须等第一次提交的代码块执行完成后,dispatch_sync()函数才会返回, // 程序才会执行到这里,才能提交第二个代码块。 dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) , ^(void){ for (int i = 0 ; i < 100; i ++) { NSLog(@"%@-----%d" , [NSThread currentThread] , i); [NSThread sleepForTimeInterval:0.1]; } });}
5.dispatch_async ,异步添加进任务队列,它不会做任何等待
dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT); NSLog(@"1"); dispatch_async(concurrentQueue, ^(){ NSLog(@"2"); [NSThread sleepForTimeInterval:5]; NSLog(@"3"); }); NSLog(@"4");
6.dispatch_queue_t
GCD队列
dispatch_queue_t disQueue =dispatch_queue_create(“队列1”, 0);
下面展示的是三种获得主线程队列的方式:
NSThread
GCD
NSOperationQueue
-(void)press{dispatch_queue_t _disQueue=dispatch_queue_create("队列1", 0); [self startDisPath]; [self runMainByThread]; [self runMainByDisPath]; [self runMainByOpration];}
-(void)startDisPath{ dispatch_queue_t global=_disQueue; dispatch_async(global, ^ { NSLog(@"=====current==%@", [NSThread currentThread]); });}-(void)runMainByThread{ [NSThread detachNewThreadSelector:@selector(update01) toTarget:self withObject:nil];}-(void)update01{ while (true) { static int i=0; i++; NSThread*main=[NSThread mainThread]; [self performSelector:@selector(updateMain) onThread:main withObject:nil waitUntilDone:YES]; if (i==1001) { [NSThread exit]; } }}-(void)updateMain{ NSLog(@"在主线程中进行");}-(void)runMainByOpration{ //获得主线程队列 NSOperationQueue*mainQueue=[NSOperationQueue mainQueue]; [mainQueue addOperationWithBlock:^{ NSLog(@"=====current==%@", [NSThread currentThread]); //在主线程中使用 updateMian [self updateMain]; }];}-(void)runMainByDisPath{ dispatch_queue_t mainDis=dispatch_get_main_queue(); // dispatch_async(mainDis, ^{ NSLog(@"=====current==%@", [NSThread currentThread]); [self updateMain]; });}
另外一个例子,GCD如何创建一个串行队列和并发队列?
@implementation FKViewController// 定义2个队列dispatch_queue_t serialQueue;dispatch_queue_t concurrentQueue;- (void)viewDidLoad{ [super viewDidLoad]; // 创建串行队列 serialQueue = dispatch_queue_create("fkjava.queue", DISPATCH_QUEUE_SERIAL); // 创建并发队列 concurrentQueue = dispatch_queue_create("fkjava.queue" , DISPATCH_QUEUE_CONCURRENT);}- (IBAction)serial:(id)sender{ // 依次将2个代码块提交给串行队列 // 必须等到第1个代码块完成后,才能执行第2个代码块。 dispatch_async(serialQueue, ^(void) { for (int i = 0 ; i < 100; i ++) { NSLog(@"%@=====%d" , [NSThread currentThread] , i); } }); dispatch_async(serialQueue, ^(void) { for (int i = 0 ; i < 100; i ++) { NSLog(@"%@------%d" , [NSThread currentThread] , i); } });}- (IBAction)concurrent:(id)sender{ // 依次将2个代码块提交给并发队列 // 两个代码块可以并发执行 dispatch_async(concurrentQueue, ^(void) { for (int i = 0 ; i < 100; i ++) { NSLog(@"%@=====%d" , [NSThread currentThread] , i); } }); dispatch_async(concurrentQueue, ^(void) { for (int i = 0 ; i < 100; i ++) { NSLog(@"%@------%d" , [NSThread currentThread] , i); } });}@end
参考来源:
http://write.blog.csdn.net/mdeditor
关于介绍GCD一篇比较好的博客(文顶顶)
http://www.cnblogs.com/wendingding/p/3806821.html
- IOS 多线程编程指南_GCD
- IOS 多线程_GCD
- iOS多线程编程指南
- IOS多线程编程指南
- [ios]多线程编程指南
- iOS多线程编程指南
- IOS多线程编程指南
- iOS多线程编程指南
- IOS多线程_GCD的简单使用和详细说明
- IOS多线程_GCD的简单使用和详细说明
- iOS_多线程_GCD
- iOS_多线程_GCD
- iOS多线程编程指南-前言
- iOS多线程编程指南-目录
- iOS多线程编程指南-前言
- iOS多线程编程指南-目录
- iOS多线程编程指南-目录
- ios osx 多线程编程指南
- poj 1390 Blocks(记忆化搜索/动态规划)
- IOS开发之简单音频播放器
- as下删除无用的图片
- Android音乐控制接口RemoteController使用
- NYOJ 题目711 最舒适的路线
- IOS 多线程编程指南_GCD
- 大数据入门:各种大数据技术介绍
- [Book Note] Haskell: Monoid
- solution Of 1098. Insertion or Heap Sort (25)
- APP事件表通用字段视图的实现
- 安装HPL、GotoBLAS2、openmpi
- gradle dsl method not found : 'android()'
- 抽象类
- java学习个人笔记---finally模块的陷阱