[IOS/翻译]GCD-1 Grand Central Dispatch

庄浩言
2023-12-01

本文是本人自己辛苦翻译的,请转载的朋友注明,翻译于Z.MJun的CSDN的博客 http://blog.csdn.net/Zheng_Paul,感谢!


翻译于2016年5月12日


Grand Central Dispatch (GCD)

Grand Central Dispatch(GCD)包含语言特征,一些运行库,和 提供了全面的系统升级,和全新的改良的执行代码可以使用在IOS和OSX的硬件上。

BSD子系统,基础代码和Cocoa的APIs的扩张,更好的让系统和你的应用跑的更快,更有效率和提高了应答速度。一个应用要有效的使用多核是很困难的,更不用说,使用在不同数量的内核的硬件,或者许多程序在这些内核里面运作。GCD,是运作在系统底层,可以更好运作所有需要运行的应用,和平衡分配系统可使用资源。

这个文档描述了GCD的API,支持能在Unix系统等级下的异步操作。你可以使用API管理,文件描述,端口,信道和时间等接口。在OSX v10.7及以上的系统,你同样可以使用GCD在文件描述器上使用通用的异步I/O操作。

GCD不局限于使用在系统级的应用,但是在你要使用到更高层级(UI)的应用上的话,你需要考虑在Cocoa上已经提供了相似并且比较容易使用的Object,如:NSOperation,和block boject. 或者其他你能使用的Object。更多咨询在Concurrency Programming Guide


Important:

当同时使用GCD和fork 系统回调时,要特别注意。当一个进程使用了GCD回调之前回调fork,在子进程中直到成功调用exec或者相关功能后在使用额外GCD回调是非常不安全的做法。


GCD对象和ARC自动释放机制

当你的应用是基于OBJ-C的,所有的调度对象都是OBJ-C的。例如,当应用使用的是ARC,调度对象的内存分配机制和其他的OBJ-C对象一样。如果不是使用ARC的,需要使用dispatch_retaindispatch_release方法来管理调度对象,而不是使用基础代码的 retain 和 release 方法
如果你需要在使用了ARC的应用下使用retain/release语法(为了保持代码的兼容性),你可以在 编译器标示 里面,使用DOS_OBJECT_USE_OBJC=0,来禁止使用基于OBJ-C的调度。

本文是本人自己辛苦翻译的,请转载的朋友注明,翻译于Z.MJun的CSDN的博客 http://blog.csdn.net/Zheng_Paul,感谢!


翻译于2016年5月12日


Grand Central Dispatch (GCD) 功能方法

创建和管理队列(Queues)

主线程 dispatch_get_main_queue

  • 描述:返回在应用的调度队列中的主线程
  • 方法:dispatch_get_main_queue(void)
  • 返回:dispatch_queue_t 类型。 返回主线程,这个队列是自动在Main函数调用前自动创建并代表主前程的
  • 系统会自动创建主调度队列和关联到应用的主线程上。应用使用以下三个调度块之间的一个,唯一一个来提交到主线程。
    • 调用 dispatch_main
    • 调用UIApplicationMain (iOS) or NSApplicationMain (OS X)
    • 使用 CFRunLoopRef在主线程。

作为全局使用的队列,在使用这个方法返回队列时,调用dispatch_suspend, dispatch_resume, dispatch_set_context,这个几个方法是没有任何效果的。

全局队列 dispatch_get_global_queue

  • 描述:通过传入不同的队列等级,来获取系统的全局队列
  • 方法:dispatch_get_global_queue( long identifier, unsigned long flags);
  • 参数:
    • identifier 通过不同的服务优先等级,系统返回任务队列。处理用户交互和用户启动任务队列要比后台运行的队列的优先级高。有以下dispatch_queue_priority_t
      • DISPATCH_QUEUE_PRIORITY_HIGH 最高等级队列,队列优先于Default,和Low
      • DISPATCH_QUEUE_PRIORITY_DEFAULT 标准等级队列,队列优先于Low,低于最高等级High
      • DISPATCH_QUEUE_PRIORITY_LOW 低等级队列,队里低于标准Default,和高等级High
      • DISPATCH_QUEUE_PRIORITY_BACKGROUND 后台等级队列,这个队列调度执行于所有的高优先等级队列和系统运行的高于后台优先等级队列的线程之后使用。这样的线程优先等级最低,任何磁盘I / O被节流,以尽量减少系统的影响。
    • flags 标记以保留以供使用。一般情况下使用 0。
  • 返回:dispatch_queue_t 类型。全局队列
  • 这个方法是更具不同的优先等级返回不同的调度全局队列。同样,在这个调下,调用dispatch_suspend, dispatch_resume, dispatch_set_context,这个几个方法是没有任何效果的

任务提交到队列里都是并行运作的。

创建队列 dispatch_queue_create

  • 描述:创建一个新的带Blcokf返回的队列
  • 方法:dispatch_queue_t dispatch_queue_create( const char *label dispatch_queue_attr_t attr);
  • 参数:
    • label 在调试工具中,一个字符串的唯一ID标记队列,如仪器仪表,取样,堆栈镜头和崩溃报告。因为应用,库和架构(frameworks)都可以创建自己调度队列,一个反向DNS的命名方式。如com.example.myqueue。这个参数是选填的,也可以填写NULL。
    • attr 在OS X v10.7及以上,IOS4.3及以上,指定DISPATCH_QUEUE_SERIAL或者为NULL来创建串行队列,指定DISPATCH_QUEUE_CONCURRENT来创建一个并行队列。在以前的版本,你必须为这个参数制定NULL。类型Dispatch Queue Types
      • DISPATCH_QUEUE_SERIAL 一个调度队列按顺序执行FIFO块
      • DISPATCH_QUEUE_CONCURRENT 一个调度队列并列执行块,虽然他们同事执行块,但是可以在队列里设置同步点来创建块。
  • 返回:一个全新的调度队列
  • 在块提交后,顺序队列按顺序一一执行任务。需要注意的是,这个快被提交给独立的队列有可能被并发执行。块被提交给并发队列脱离了FIFO,单也有可能当资源能充足的条件下被执行。

当前队列 dispatch_get_current_queue

  • 描述:返回一个正在正式块的队列
  • 方法:dispatch_get_current_queue( void)
  • 返回:放回当前队列
  • 这个方法的范围会不可能为NULL。当通过外面的块来响应并且响应在主线程调用,这个方法会从主线程返回。如果响应的是在其他线程,那么这个方法将会返回其他执行队列。
  • 这个方法适用于:OS X v10.6–v10.9 IOS v4.0–v6.0

队列属性 dispatch_queue_attr_make_with_qos_class

  • 描述:通过传入指定的参数,返回队列的属性
  • 方法 dispatch_queue_attr_make_with_qos_class( dispatch_queue_attr_t attr, int qos_class, int relative_priority);
  • 参数:
    • attr NULL或者DISPATCH_QUEUE_SERIAL返回串行队列,DISPATCH_QUEUE_CONCURRENT则是并行队列。
    • qos_class 传入不同的优先级,如dispatch_queue_priority_t,但是在应用上,有所不一样,输入值为qos_class_t
      • QOS_CLASS_USER_INTERACTIVE
      • QOS_CLASS_USER_INITIATED对应DISPATCH_QUEUE_PRIORITY_HIGH
      • QOS_CLASS_DEFAULT对应DISPATCH_QUEUE_PRIORITY_DEFAULT
      • QOS_CLASS_UTILITY对应DISPATCH_QUEUE_PRIORITY_LOW
      • QOS_CLASS_BACKGROUND对用DISPATCH_QUEUE_PRIORITY_BACKGROUND
      • QOS_CLASS_UNSPECIFIED
    • relative_priority 负偏移值。这里填写的必须是一个小于0和大于MIN_QOS_CLASS_PRIORITY的数值。
  • 返回:dispatch_queue_attr_t类型,返回属性有可能是通过dispatch_queue_create这个方法创建的调度队列。
  • 当你想创建一个具有服务等级质量的调度队列之前调用这个方法。这个方法与你传入的参数来返回一个你能调用dispatch_queue_create方法的值。The quality-of-service value you specify using this function takes precedence over the priority level inherited from the dispatch queue’s target queue.
  • 这个方法适用于:OS X v10.7 IOS v8.0

队列标识 dispatch_queue_get_label

  • 描述:返回已经被创建的队列的标识
  • 方法:const char * dispatch_queue_get_label(dispatch_queue_t queue)
  • 参数:queue 队列不能为空
  • 返回:队列的标识,如果队列的标识是NULL,返回也会是NULL。

目标队列dispatch_set_target_queue

  • 描述:为提供的object设置目标队列
  • 方法:void dispatch_set_target_queue( dispatch_object_t object, dispatch_queue_t queue)
  • 参数:
    • object 要修改的对象,对象不能为NULL
    • queue 为对象设置队列目标。这个队列会被保留,并且如果存在前一个,前一个会被释放。这个参数不能为NULL。
  • 一个对象的目标队列处理一个对象,这个目标队列决定了这个队列调用哪个对象的finalizer。另外,修改某些对象的目标队列,改变对象的行为。

    • 调度队列,一个调度队列的优先继承于目标队列。使用dispatch_get_global_queue这个方法获得一个 你期望的目标队列。如果你提交一个块到串行队列和这个串行队里的目标队列是不同于其他串行队列。那么这个块将不会并发调用,或者其他队列也有相同的目标队列。

    Important

    如果你为一个队列修改目标队列,你必须保证不会在队列里产生死循环。

    • 调度资源,用来控制或者取消被提交的块的控制
    • 调度I/O渠道,用来执行I/O操作。这可能影响I/O操作的结构的优先度。例如,如果目标队列的优先级别设置成DISPATCH_QUEUE_PRIORITY_BACKGROUND,那么他的I/O操作在I/O连接后,通过Using the Dispatch I/O Convenience API执行。
      • dispatch_read
      • dispatch_write

主调度dispatch_main

  • 描述:执行提交给主调度的块
  • 方法:void dispatch_main( void);
  • 返回:没有返回
  • 这个方法在主线程里,和等待块提交给主线程。应用调用UIApplicationMain (iOS), NSApplicationMain (OS X), or CFRunLoopRun在主线程里,不能调用这个方法。
 类似资料: