dispatch对象


[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 原文地址  http://www.cnblogs.com/sunfrog/p/3243230.html  
  2.   
  3. 谈起iOS的dispatch(正式称谓是Grand Central Dispatch或GCD),不得不说这又是iOS(包括MacOSX)平台的创新,优缺点这里不讨论,只有当你使用时才能真正体会到。我们说dispatch函数的主要目的是实现多任务并发代码,那么要理解dispatch函数,先来了解dispatch对象的定义。  
  4.   
  5.    
  6.   
  7. dispatch对象类型的部分定义,主要使用C语言的宏定义:  
  8.   
  9. <os/object.h>文件:  
  10.   
  11. #define OS_OBJECT_CLASS(name) OS_##name  
  12.   
  13. #define OS_OBJECT_DECL(name, ...) \  
  14.   
  15. @protocol OS_OBJECT_CLASS(name) __VA_ARGS__ \  
  16.   
  17. @end \  
  18.   
  19. typedef NSObject<OS_OBJECT_CLASS(name)> *name##_t  
  20.   
  21. #define OS_OBJECT_DECL_SUBCLASS(name, super) \  
  22.   
  23. OS_OBJECT_DECL(name, <OS_OBJECT_CLASS(super)>)  
  24.   
  25.    
  26.   
  27. <dispatch/object.h>文件:  
  28.   
  29. #define DISPATCH_DECL(name) OS_OBJECT_DECL_SUBCLASS(name, dispatch_object)  
  30.   
  31. #define DISPATCH_GLOBAL_OBJECT(type, object) ((OS_OBJECT_BRIDGE type)&(object))  
  32.   
  33. OS_OBJECT_DECL(dispatch_object); //定义dispatch_object_t  
  34.   
  35.    
  36.   
  37. <dispatch/queue.h>文件(dispatch队列类定义,其它dispatch对象类似):  
  38.   
  39. DISPATCH_DECL(dispatch_queue); //定义dispatch_queue_t  
  40.   
  41.    
  42.   
  43. 可以通过Xcode预编译后可以看到最终结果,最终定义的都是NSObject类,虽然它们之间没用直接继承关系,但都实现OS_dispatch_object接口,这样dispatch_queue_t对象也同样是dispatch_object_t的对象了。下面就是预编译dispatch_object_t和dispatch_queue_t的结果:  
  44.   
  45. @protocol OS_dispatch_object  
  46.   
  47. @end  
  48.   
  49. typedef NSObject<OS_dispatch_object> *dispatch_object_t;  
  50.   
  51. @protocol OS_dispatch_queue <OS_dispatch_object>  
  52.   
  53. @end  
  54.   
  55. typedef NSObject<OS_dispatch_queue> *dispatch_queue_t;  
  56.   
  57.    
  58.   
  59. 由于dispatch api接口定义成C函数的形式,dispatch的对象都是由C函数形式的厂方法得到(不能继承dispatch类,不用alloc),这样做隐藏dispatch对象的具体形态,把注意力放在如何调用dispatch api上。  
  60.   
  61. 从上面dispatch对象宏定义可以看到dispatch对象类的名称一般为dispatch_xyz_t(严格来讲是对象指针),它们都可以看成dispatch_object_t的子类(对象指针),所以使用dispatch对象时套用这个概念就行。  
  62.   
  63.    
  64.   
  65. 有关dispatch对象的基本接口如下:  
  66.   
  67. void dispatch_retain(dispatch_object_t object); //替代dispatch对象常规的retain来持有对象,但ARC编程中不再允许  
  68.   
  69. void dispatch_release(dispatch_object_t object); //替代dispatch对象常规的release来释放对象,同样ARC编程中不再允许  
  70.   
  71. void dispatch_set_context(dispatch_object_t object, voidvoid *context); //给dispatch对象绑定特定数据对象(类似线程的TLS数据),会被传给dispatch对象的finalizer函数  
  72.   
  73. voidvoid *dispatch_get_context(dispatch_object_t object); //返回dispatch对象绑定的数据对象指针  
  74.   
  75. void dispatch_set_finalizer_f(dispatch_object_t object, dispatch_function_t finalizer); //设置dispatch对象的finalizer函数,当该对象释放时会调用finalizer,部分代码解释如何使用这个函数(ARC模式):  
  76.   
  77. dispatch_object_t dispatchObject = ...;  
  78.   
  79. voidvoid *context = ...;  
  80.   
  81. dispatch_set_context(dispatchObject, context);  
  82.   
  83. dispatch_set_finalizer_f(dispatchObject, finalizer);  
  84.   
  85. ......  
  86.   
  87. dispatchObject = nil//dispatchObject被释放,这时调用finalizer函数  
  88.   
  89. ......  
  90.   
  91. void finalizer(voidvoid *context)  
  92.   
  93. {  
  94.   
  95.   //处理或释放context相关资源  
  96.   
  97. }  
  98.   
  99.    
  100.   
  101. dispatch对象的另外两个接口是:  
  102.   
  103. void dispatch_resume(dispatch_object_t object); //激活(启动)在dispatch对象上的block调用,可以运行多个block  
  104.   
  105. void dispatch_suspend(dispatch_object_t object); //挂起(暂停)在dispatch对象上的block调用,已经运行的block不会停止  
  106.   
  107. 一般这两个函数的调用必须成对,否则运行会出现异常。  
  108.   
  109. 至此你是否发现这两个函数有些与众不同呢?好像从来没有这么使用对象的,启动对象--暂停对象,呵呵。这正是理解dispatch对象的关键所在。dispatch对象其实是抽象的任务,把动态的任务变成对象来管理。任务是动态的,不存在继承关系,这就是为什么GCD没有提供静态继承dispatch对象类的方式。如果能这样理解,那么在使用dispatch函数时就能够更灵活地去编写代码,实现各种并发的多任务代码。  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值