谈起iOS的dispatch(正式称谓是Grand Central Dispatch或GCD),不得不说这又是iOS(包括MacOSX)平台的创新,优缺点这里不讨论,只有当你使用时才能真正体会到。我们说dispatch函数的主要目的是实现多任务并发代码,那么要理解dispatch函数,先来了解dispatch对象的定义。

dispatch对象类型的部分定义,主要使用C语言的宏定义:

<os/object.h>文件:

#define OS_OBJECT_CLASS(name) OS_##name

#define OS_OBJECT_DECL(name, ...) \

@protocol OS_OBJECT_CLASS(name) __VA_ARGS__ \

@end \

typedef NSObject<OS_OBJECT_CLASS(name)> *name##_t

#define OS_OBJECT_DECL_SUBCLASS(name, super) \

OS_OBJECT_DECL(name, <OS_OBJECT_CLASS(super)>)

<dispatch/object.h>文件:

#define DISPATCH_DECL(name) OS_OBJECT_DECL_SUBCLASS(name, dispatch_object)

#define DISPATCH_GLOBAL_OBJECT(type, object) ((OS_OBJECT_BRIDGE type)&(object))

OS_OBJECT_DECL(dispatch_object); //定义dispatch_object_t

<dispatch/queue.h>文件(dispatch队列类定义,其它dispatch对象类似):

DISPATCH_DECL(dispatch_queue); //定义dispatch_queue_t

可以通过Xcode预编译后可以看到最终结果,最终定义的都是NSObject类,虽然它们之间没用直接继承关系,但都实现OS_dispatch_object接口,这样dispatch_queue_t对象也同样是dispatch_object_t的对象了。下面就是预编译dispatch_object_t和dispatch_queue_t的结果:

@protocol OS_dispatch_object

@end

typedef NSObject<OS_dispatch_object> *dispatch_object_t;

@protocol OS_dispatch_queue <OS_dispatch_object>

@end

typedef NSObject<OS_dispatch_queue> *dispatch_queue_t;

由于dispatch api接口定义成C函数的形式,dispatch的对象都是由C函数形式的厂方法得到(不能继承dispatch类,不用alloc),这样做隐藏dispatch对象的具体形态,把注意力放在如何调用dispatch api上。

从上面dispatch对象宏定义可以看到dispatch对象类的名称一般为dispatch_xyz_t(严格来讲是对象指针),它们都可以看成dispatch_object_t的子类(对象指针),所以使用dispatch对象时套用这个概念就行。

有关dispatch对象的基本接口如下:

void dispatch_retain(dispatch_object_t object); //替代dispatch对象常规的retain来持有对象,但ARC编程中不再允许

void dispatch_release(dispatch_object_t object); //替代dispatch对象常规的release来释放对象,同样ARC编程中不再允许

void dispatch_set_context(dispatch_object_t object, void *context); //给dispatch对象绑定特定数据对象(类似线程的TLS数据),会被传给dispatch对象的finalizer函数

void *dispatch_get_context(dispatch_object_t object); //返回dispatch对象绑定的数据对象指针

void dispatch_set_finalizer_f(dispatch_object_t object, dispatch_function_t finalizer); //设置dispatch对象的finalizer函数,当该对象释放时会调用finalizer,部分代码解释如何使用这个函数(ARC模式):

dispatch_object_t dispatchObject = ...;

void *context = ...;

dispatch_set_context(dispatchObject, context);

dispatch_set_finalizer_f(dispatchObject, finalizer);

......

dispatchObject = nil; //dispatchObject被释放,这时调用finalizer函数

......

void finalizer(void *context)

{

  //处理或释放context相关资源

}

 

dispatch对象的另外两个接口是:

void dispatch_resume(dispatch_object_t object); //激活(启动)在dispatch对象上的block调用,可以运行多个block

void dispatch_suspend(dispatch_object_t object); //挂起(暂停)在dispatch对象上的block调用,已经运行的block不会停止

一般这两个函数的调用必须成对,否则运行会出现异常。

至此你是否发现这两个函数有些与众不同呢?好像从来没有这么使用对象的,启动对象--暂停对象,呵呵。这正是理解dispatch对象的关键所在。dispatch对象其实是抽象的任务,把动态的任务变成对象来管理。任务是动态的,不存在继承关系,这就是为什么GCD没有提供静态继承dispatch对象类的方式。如果能这样理解,那么在使用dispatch函数时就能够更灵活地去编写代码,实现各种并发的多任务代码。

iOS多线程的初步研究(七)-- dispatch对象的更多相关文章

  1. iOS多线程的初步研究1

    iOS多线程的初步研究(一) 对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NS ...

  2. iOS多线程的初步研究(六)

    iOS多线程的初步研究(六) iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管 ...

  3. iOS多线程的初步研究3

    iOS多线程的初步研究(三) 弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run ...

  4. iOS多线程的初步研究

    iOS多线程的初步研究(四) 理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的. 先看看NSTimer的两个常用方法: + (NST ...

  5. iOS多线程的初步研究(一)-- NSThread

    对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NSThread.一般构造NSTh ...

  6. iOS多线程的初步研究(八)-- dispatch队列

    GCD编程的核心就是dispatch队列,dispatch block的执行最终都会放进某个队列中去进行,它类似NSOperationQueue但更复杂也更强大,并且可以嵌套使用.所以说,结合bloc ...

  7. iOS多线程的初步研究(九)-- dispatch源

    dispatch源(dispatch source)和RunLoop源概念上有些类似的地方,而且使用起来更简单.要很好地理解dispatch源,其实把它看成一种特别的生产消费模式.dispatch源好 ...

  8. iOS多线程的初步研究(十)-- dispatch同步

    GCD提供两种方式支持dispatch队列同步,即dispatch组和信号量. 一.dispatch组(dispatch group) 1. 创建dispatch组 dispatch_group_t ...

  9. iOS多线程的初步研究(六)-- NSOperation

    iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实 ...

随机推荐

  1. Android操作系统11种传感器介绍

    我们依次看看这十一种传感器 1 加速度传感器 加速度传感器又叫G-sensor,返回x.y.z三轴的加速度数值. 该数值包含地心引力的影响,单位是m/s^2. 将手机平放在桌面上,x轴默认为0,y轴默 ...

  2. 在linux上使用yum安装JDK

    1.查找java相关得列表 [qyf@localhost ~]$ yum -y list java* 执行结果 [qyf@localhost ~]$ yum -y list java* Loaded ...

  3. 条款24:若所有的函数参数可能都需要发生类型转换才能使用,请采用non-member函数

    假设有一个有理数类Rational,有一个计算有理数乘法的成员函数operator*,示例如下: #include <iostream> class Rational { public: ...

  4. Entity Framework学习笔记(二)----CRUD(1)

    请注明转载地址:http://www.cnblogs.com/arhat 这篇文章老魏和大家分享一下Entity Framework的CRUD操作,在这之前呢,老魏先说一下老魏对EF的一个整体的认识, ...

  5. [shell基础]——cut命令

    cut命令常见选项

  6. [shell基础]——read命令

    read命令:在shell中主要用于读取输入.变量.文本 1. 接受标准输入(键盘)的输入,并将输入的数据赋值给设置的变量      [按回车键——表示输入完毕]      [若输入的数据多于设置的变 ...

  7. CAD字体显示错乱问题解决方案

    最近这两天一直在画竣工图,用CAD用得挺多的,所以老是发现一些问题.今天在打开别人发过来的图纸时,我看到竟然还有钢筋符号无法显示…… 像这种问题的解决,据我所知就两种方法: 一.替换使用的字体 首先选 ...

  8. 对C++中高内聚,低耦合原则的理解

    1.C语言是面向过程的语言,采用模块化的设计思想,每个功能划分为一个模块,是以函数为单位的. 2.C++是面向对象的语言,采用类设计的思想,因此C++中的模块是以类为基本单位的. 高内聚,低耦合能够使 ...

  9. 如何解决读取到文件末尾时碰到EOF导致的重复输出或者无用输出

    当读取到文件末尾时,会碰到EOF,如何解决呢?    方法一:我们可以通过(ch=fin.get())!=EOF来结束读取,这样就不会像eof()那样碰到EOF之后,还会再进行一次读取,导致输出一个无 ...

  10. Mysql 导出数据库和指定表中的数据

    参考地址:http://jingyan.baidu.com/article/b7001fe14240ab0e7282dde9.html [root@youo zw]# mysqldump -u roo ...