附录-OC源码-GCD:源码中使用的宏

数据结构中使用的宏

一些宏, 逻辑上没啥可说的, 就是单纯代码拼接.
但要注意的, _OS_OBJECT_HEADER, OS_OBJECT_STRUCT_HEADER, _DISPATCH_OBJECT_HEADER
整体链条如下:
DISPATCH_OBJECT_HEADER -> _DISPATCH_OBJECT_HEADER -> OS_OBJECT_STRUCT_HEADER -> _OS_OBJECT_HEADER

这三个宏中的字段, 在大部分的基础结构体中都有, 可以理解为 GCD 的基础结构有这样下面的特性

  • 准备作为链表节点使用, 都拥有 do_next 指向下一个节点的指针
  • 都需要包含当前执行的队列 do_targetq
  • 包含 do_ctxt 作为上下文, do_finalizer 作为析构函数
  • 都拥有一个 isa 指针, 这个 isa 类型是结构体名字_vtable_s, 字段名为do_vtable
  • 都拥有一个内部引用计数和一个外部引用计数
  • _as_os_obj 暂时不知道干嘛的

    _DISPATCH_OBJECT_HEADER

    #define _DISPATCH_OBJECT_HEADER(x) \  
    struct _os_object_s _as_os_obj[0]; \  
    OS_OBJECT_STRUCT_HEADER(dispatch_##x); \  
    struct dispatch_##x##_s *volatile do_next; \  
    struct dispatch_queue_s *do_targetq; \  
    void *do_ctxt; \  
    void *do_finalizer  
    

OS_OBJECT_STRUCT_HEADER

#define OS_OBJECT_STRUCT_HEADER(x) \  
  _OS_OBJECT_HEADER(\  
  const struct x##_vtable_s *do_vtable, \  
  do_ref_cnt, \  
  do_xref_cnt)  
#endif  

_OS_OBJECT_HEADER

#define _OS_OBJECT_HEADER(isa, ref_cnt, xref_cnt) \  
        isa; /* must be pointer-sized */ \  
        int volatile ref_cnt; \  
        int volatile xref_cnt  

DISPATCH_GLOBAL_OBJECT_HEADER 在 global, main queue 初始化时常见

其实是对上面提到的字段的初始化
其中do_vtable, 层层宏解开后是 OS_dispatch_##name##_class
两个引用计数, 最终使用的是INT_MAX

#define _OS_OBJECT_GLOBAL_REFCNT INT_MAX  
#define DISPATCH_VTABLE(name) DISPATCH_OBJC_CLASS(name)  
#define DISPATCH_OBJC_CLASS(name) (&DISPATCH_CLASS_SYMBOL(name))  
#define DISPATCH_CLASS_SYMBOL(name) OS_dispatch_##name##_class  
  
#define DISPATCH_GLOBAL_OBJECT_HEADER(name) \  
  .do_vtable = DISPATCH_VTABLE(name), \  
  .do_ref_cnt = DISPATCH_OBJECT_GLOBAL_REFCNT, \  
  .do_xref_cnt = DISPATCH_OBJECT_GLOBAL_REFCNT  
#endif  

调用中常见的宏

_DISPATCH_ROOT_QUEUE_IDX

主要是将传入的名字 n, 通过 flags 决定拼接成 QOS_OverCommit 还是 qos
这个生成的内容将会是初始化生成的全局队列的数组序号, 这个序号同时也会被宏转为优先级的 enum

#define _DISPATCH_ROOT_QUEUE_IDX(n, flags) \  
    ((flags & DISPATCH_PRIORITY_FLAG_OVERCOMMIT) ? \  
    DISPATCH_ROOT_QUEUE_IDX_##n##_QOS_OVERCOMMIT : \  
    DISPATCH_ROOT_QUEUE_IDX_##n##_QOS)  

_DISPATCH_ROOT_QUEUE_ENTRY

生成一个dispatch_queue_global_s, 并且将其按计算出来的序号装入数组中

#define _DISPATCH_ROOT_QUEUE_ENTRY(n, flags, ...) \  
  [_DISPATCH_ROOT_QUEUE_IDX(n, flags)] = { \  
    DISPATCH_GLOBAL_OBJECT_HEADER(queue_global), \  
    .dq_state = DISPATCH_ROOT_QUEUE_STATE_INIT_VALUE, \  
    .do_ctxt = _dispatch_root_queue_ctxt(_DISPATCH_ROOT_QUEUE_IDX(n, flags)), \  
    .dq_atomic_flags = DQF_WIDTH(DISPATCH_QUEUE_WIDTH_POOL), \  
    .dq_priority = flags | ((flags & DISPATCH_PRIORITY_FLAG_FALLBACK) ? \  
        _dispatch_priority_make_fallback(DISPATCH_QOS_##n) : \  
        _dispatch_priority_make(DISPATCH_QOS_##n, 0)), \  
    __VA_ARGS__ \  
  }