IOS开发 GCD多线程编程技术(二)

原创 2014年03月06日 23:23:53

六、使用Dispatch Source 来实现简单的回调函数 


1、它有什么用

        dispatch source 的作用是负责监听事件,先看看它的构造函数。

   dispatch_source_create(dispatch_source_type_t type,
   uintptr_t handle,
   unsigned long mask,
   dispatch_queue_t queue);

       第1个参数:要监听的事件类型

       第2个参数:可以理解为句柄、索引或id,假如要监听进程,需要传入进程的ID

       第3个参数:根据参数2,可以理解为描述,提供更详细的描述,让它知道具体要监听什么

       第4个参数:当事件发生时,将block添加至哪个队列来执行


2、可监听事件的类型


        DISPATCH_SOURCE_TYPE_TIMER        定时响应

        DISPATCH_SOURCE_TYPE_SIGNAL      接收到UNIX信号时响应

        DISPATCH_SOURCE_TYPE_READ   IO操作,如对文件的操作、socket操作的读响应

        DISPATCH_SOURCE_TYPE_WRITE     IO操作,如对文件的操作、socket操作的写响应   

        DISPATCH_SOURCE_TYPE_VNODE    文件状态监听,文件被删除、移动、重命名

        DISPATCH_SOURCE_TYPE_PROC  进程监听,如进程的退出、创建一个或更多的子线程、进程收到UNIX信号

        DISPATCH_SOURCE_TYPE_MACH_SEND

        DISPATCH_SOURCE_TYPE_MACH_RECV   上面2个都属于Mach相关事件响应

        DISPATCH_SOURCE_TYPE_DATA_ADD

        DISPATCH_SOURCE_TYPE_DATA_OR          上面2个都属于自定义的事件,并且也是有自己来触发


3、怎么使用


 (一)自定义事件(DISPATCH_SOURCE_TYPE_DATA_ADD、DISPATCH_SOURCE_TYPE_DATA_OR),先看代码

    dispatch_source_t source =dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());
    dispatch_source_set_event_handler(source,^{
           NSLog(@"监听函数:%lu",dispatch_source_get_data(source));
    });
    dispatch_resume(source);
   
    dispatch_queue_t myqueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL);
    dispatch_async(myqueue, ^ {
          int i;
          for(i = 0;i<4;i++){
             dispatch_source_merge_data(source,i);
          }
    });

首先使用dispatch_source_create函数创建dispatchsource,第1个参数表示它是一个自定义的_ADD类型的监听,具体作用后面说,2、3参数这里面没有作用设置为0即可,第4个参数表示一旦事件触发就将要执行的代码块添加到主队列中执行,接着我们使用dispatch_source_set_event_handler函数为这个监听设置事件的源和响应体,第1个参数表示这个监听是响应用户自定义事件的,也就是我们上面定义的dispatchsource,第2个参数是负责响应的代码块。很有意思的是当我们创建监听后,这个监听默认是挂起的,需要手动恢复,所以我们使用dispatch_resume函数恢复这个监听,为了测试这个监听,我们后面又通过for循环触发事件,触发事件的函数就是dispatch_source_merge_data,这个函数负责触发自定义事件,第1个参数表示要触发哪个监听,第2个参数是向监听传入一个unsigned long 类型的值, 我们这里传入循环的索引,好了,整体来看这段程序,dispatch_source_merge_data函数会被执行4次,并分别传入0、1、2、3这4个值,既然dispatch_source_merge_data负责触发事件,那么我们在监听里面的响应体应该会监听到,结果也确实监听到了,但是并不是我们想象的那样打印4次,而是只打印了一次,打印结果是4次传入值相加的和,也就是6,这就是DISPATCH_SOURCE_TYPE_DATA_ADD参数的作用,这个监听在创建之初就被设置为自定义监听,并且会把监听结果相加,然后统一响应。这里你应该会奇怪,既然结果会相加并统一响应,那跟触发的时候加好,然后触发一次有什么区别呢,好吧,我们把触发事件的for循环改一下,然后再运行,看看会发生什么

  for(i = 0;i<4;i++){
      dispatch_source_merge_data(source,i);
      [NSThread sleepForTimeInterval:0.0001];
  }

我们在触发事件的地方加上0.0001秒的延迟,然后运行整个程序多次,你会发现奇怪的现象,我们同样是触发4次事件,但是响应的次数变成不确定了,可能是1次,也可能是2次,如果你将延迟时间设置长点,甚至设置为0点几秒就能让响应的次数变为固定的4次,为什么会这样呢,其实这就是这个自定义事件设计的初衷。如果同一时间同一个事件被触发的频率非常密集,那么dispatchsource会将这些密集的响应相加统计做出响应,但是如果触发的相对零散,那么dispatch source会分别进行响应,这其实是在智能的控制UI的没必要的更新操作,因为那些几乎在同一时间更新进度条的操作完全可以统一进行更新,没有必要每次都更新一下。这样做也会减少UI线程的负担,例如更新进度条的同时,你的UI可能还在同时响应用户的输入、触碰等工作。当然你可以选择实时更新,办法就是直接使用使用dispatch_async直接更新界面。Dispatch source在统一响应完毕后计数变为0,后面再触发的会重新相加。DISPATCH_SOURCE_TYPE_DATA_OR会将所有监听到的值逻辑与操作,然后统一触发。貌似没有DISPATCH_SOURCE_TYPE_DATA_ADD常用。

 



IOS开发 GCD多线程编程技术(一)

一、 概念                   GCD技术全称 Grand Central Dispatch 译为中央调度,是一种更简单、更高效的多线程编程解决方案,在mac 10.6雪豹及IOS...
  • u011969457
  • u011969457
  • 2014年03月06日 10:05
  • 620

iOS开发多线程GCD(二)

一、分组 /* 分组的主要目的 是判断一组操作 是否全部执行结束 原理 将需要执行的操作 添加到同一个分组下 如果其中的某一个操作结束 就会组中移除 当组里面的操作数变为0的 说明...
  • u010067452
  • u010067452
  • 2017年03月17日 17:47
  • 222

iOS开发-多线程编程技术(Thread、Cocoa operations、GCD)

前言:在软件开发中,多线程编程技术被广泛应用,相信多线程任务对我们来说已经不再陌生了。有了多线程技术,我们可以同做多个事情,而不是一个一个任务地进行。比如:前端和后台作交互、大任务(需要耗费一定的时间...
  • qq_25340321
  • qq_25340321
  • 2015年03月02日 11:33
  • 509

多线程学习10-GCD的线程间通信

学习多线程10(之前跟着小码哥视频学习了多线程,准备把学到的东西放到网上,便于参考。仅有视频,所以所有文字都是自己打的,同时也温习一下多线程) GCD的线程间通信,简单事例(下载图片)。 #i...
  • Leemin_ios
  • Leemin_ios
  • 2016年04月19日 21:08
  • 1093

ios开发单例模式——使用GCD实现单例模式 & 非ARC单例模式 &使用GCD和线程锁实现单例模式

使用GCD和线程锁实现单例模式 static dispatch_once_t once; dispatch_once(&once,^{ } @synchronized(sel...
  • sunnyboy9
  • sunnyboy9
  • 2015年04月05日 23:51
  • 8821

【iOS开发】GCD异步操作(迭代篇。。。)

一、GCD编程异步 // 异步线程 dispatch_async(dispatch_get_global_queue(0, 0), ^{ // 处理耗时操作的代码块......
  • Hanrovey
  • Hanrovey
  • 2016年11月23日 10:09
  • 646

iOS 多线程: 正确认识 GCD 队列类型

在面试或者跟一些有 ios 编程经验的人聊到关于 GCD 的队列类型的问题. 很多人说自定义的 queue 是串行队列. 这种说法在一定程度上面是不对的. 今天跟大家聊聊 GCD 中的队列类型问题. ...
  • AndroidBluetooth
  • AndroidBluetooth
  • 2015年11月01日 00:09
  • 2709

c++中的多线程编程技术Createthread()

CreateThread用法详解 C++中的多线程编程技术,C++本身并没有提供任何多线程机制,但是在windows下,我们可以调用SDK win32 api来编写多线程的程序:   创建线...
  • ghevinn
  • ghevinn
  • 2012年09月28日 16:08
  • 2544

猫猫学iOS(五十一)多线程网络之GCD下载合并图片_队列组的使用

猫猫分享,必须精品原创文章,欢迎转载。转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents合并图片(图片水印)第一种方...
  • u013357243
  • u013357243
  • 2015年05月23日 19:39
  • 2379

iOS多线程开发—— GCD dispatch_semaphore 信号量

在GCD中提供了一种信号机制,也可以解决资源抢占问题(和同步锁的机制并不一样)。 GCD中信号量是dispatch_semaphore_t类型,支持信号通知和信号等待。每当发送一个信号通知,则信号量 ...
  • xiao__L
  • xiao__L
  • 2016年11月01日 10:37
  • 342
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IOS开发 GCD多线程编程技术(二)
举报原因:
原因补充:

(最多只允许输入30个字)