iOS多线程的初步研究(七)-- dispatch对象
谈起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对象的更多相关文章
- iOS多线程的初步研究1
iOS多线程的初步研究(一) 对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NS ...
- iOS多线程的初步研究(六)
iOS多线程的初步研究(六) iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管 ...
- iOS多线程的初步研究3
iOS多线程的初步研究(三) 弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run ...
- iOS多线程的初步研究
iOS多线程的初步研究(四) 理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的. 先看看NSTimer的两个常用方法: + (NST ...
- iOS多线程的初步研究(一)-- NSThread
对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NSThread.一般构造NSTh ...
- iOS多线程的初步研究(八)-- dispatch队列
GCD编程的核心就是dispatch队列,dispatch block的执行最终都会放进某个队列中去进行,它类似NSOperationQueue但更复杂也更强大,并且可以嵌套使用.所以说,结合bloc ...
- iOS多线程的初步研究(九)-- dispatch源
dispatch源(dispatch source)和RunLoop源概念上有些类似的地方,而且使用起来更简单.要很好地理解dispatch源,其实把它看成一种特别的生产消费模式.dispatch源好 ...
- iOS多线程的初步研究(十)-- dispatch同步
GCD提供两种方式支持dispatch队列同步,即dispatch组和信号量. 一.dispatch组(dispatch group) 1. 创建dispatch组 dispatch_group_t ...
- iOS多线程的初步研究(六)-- NSOperation
iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实 ...
随机推荐
- chrome下的js调试
console输出对象信息:console.log(object[,object,.....])
- Linux 常见的进程调度算法
1.在介绍进程调度之前,先对进程的状态的概念应该有所了解,下面是关于进程状态的一些基本概念:进程的状态分为三种,分别为: 1).运行态:该状态表明进程在实际占用CPU 2).就绪态: 该状态下进程可以 ...
- 微信支付开发,再次签名,APP调用
1.商户服务器生成支付订单,先调用[统一下单API]生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付. 再次生成签名的时候,按照接口: https://pay.weixin.q ...
- Java通过SpyMemcached来缓存数据
配置好Magent+memcached后,很明显数据之间的输入与输出都是通过代理服务器的,magent是做代理服务器的很明显java在memecached的调用驱动在magent同样适用. 这里选择S ...
- Android中修改状态栏的颜色和我们App的风格一致
其实也没什么东西,就是一个主题,下面看代码: <resources> <!-- Base application theme. --> <style name=" ...
- hdu 2094 产生冠军
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2094 产生冠军 Description 有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比 ...
- JVM学习总结一——内存模型
JVM是java知识体系的基石之一,任何一个java程序的运行,都要借助于他.或许对于我这种初级程序员而言,工作中很少有必要刻意去关注JVM,然而如果能对这块知识有所了解,就能够更清晰的明白程序的运行 ...
- mvvm 模式
MVC = Massive View Controller ? 有笑话称MVC为重量级的试图控制器.仔细一想,确实存在这个问题.以UITableViewController和UITableView举个 ...
- AngularJS与RequireJS集成方案
关于angularjs.requirejs的基础知识请自行学习 一.简单事例的项目目录如下: -index.html -scripts文件夹 --controller文件夹 --- mianContr ...
- scjp考试准备 - 1 - 循环控制
判断如下代码最后的执行结果. public class Breaker{ static String o = ""; public static void main(String[ ...