iOS多线程的初步研究(七)-- dispatch对象

时间:2023-01-03 08:10:05

谈起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. PostgreSql性能测试

    # PostgreSql性能测试 ## 1. 环境+ 版本:9.4.9+ 系统:OS X 10.11.5+ CPU:Core i5 2.7G+ 内存:16G+ 硬盘:256G SSD ## 2. 测试 ...

  2. Android Activity的加载模式和onActivityResult方法之间的冲突

    前言 今天在调试程序时,发现在某一Activity上点击返回键会调用该Activity的onActivityResult()方法.我一开始用log,后来用断点跟踪调试半天,还是百思不得其解.因为之前其 ...

  3. 将序列设置为字段的默认值 - oracle

    1.表结构中log_id 非空.且为主键字段 create table TL_M_QRTZ_LOG( log_id NUMBER(8) not null, job_id NUMBER(8) not n ...

  4. js异步加载 defer和async 比较

    网上说法很多,很少一句话能总结清楚的,终于找到两句一针见血的描述,很到位: 相同点:都不阻塞DOM解析 defer  :顺序:保证先后顺序.解析:HTML 解析器遇到它们时,不阻塞(脚本将被异步下载) ...

  5. 高放的c&plus;&plus;学习笔记之重载运算与类型转换

    ▲基本概念 (1)重载运算符是具有特殊名字的函数,它们的名字又operator和其后要定义的运算符号共同构成.. (2)对于一个运算符号来说它或者是类的成员,或者至少含有一个类类型的参数. (3)我们 ...

  6. hdu1166 敌兵布阵

    敌兵布阵 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动 ...

  7. spring为什么推荐使用构造器注入?

    闲谈 ​ Spring框架对Java开发的重要性不言而喻,其核心特性就是IOC(Inversion of Control, 控制反转)和AOP,平时使用最多的就是其中的IOC,我们通过将组件交由Spr ...

  8. webapi框架搭建-webapi异常处理

    webapi框架搭建系列博客 前言 上一篇我们已经完成了项目的日志管理,在项目开发中日志会经常记录程序中的异常,供后续问题排查使用.本篇讲如何在webapi里加入异常处理机制. 目的和原则 1.程序任 ...

  9. curator 实现分布式一致性锁

    最近准备在项目中引入分布式锁,故而研究基于zookeeper的curator框架. 网上资料不多,自己研究其源码发现,这个框架已经帮我做了很多现成的实现. 下面介绍下锁的实现: 通过源码中Lockin ...

  10. Event 事件

    事件是建立在委托的基础之上的. http://www.cnblogs.com/lystory/p/5085786.html public class 事件参数 { public 事件参数(string ...