更多文章关注公众号【白羊哈哈】
iOS GCD 对外提供了Objective-C
的接口,但是真正实现功能的是内部定义的C
结构体,本文继《GCD Inside: 数据结构(一)》
之后,继续列举 GCD 中使用到的数据结构。
本文只是列举数据结构的定义,数据结构中字段的含义会在后续文章中讲解。
1 _os_object_s
_os_object_s
定义如下:
c
// 1. src/object_internal.h
typedef struct _os_object_s {
_OS_OBJECT_HEADER(
const _os_object_vtable_s *__ptrauth_objc_isa_pointer os_obj_isa,
os_obj_ref_cnt,
os_obj_xref_cnt);
} _os_object_s;
上面代码中宏_OS_OBJECT_HEADER
定义如下:
c
// 1. os/object_private.h
#define _OS_OBJECT_HEADER(isa, ref_cnt, xref_cnt) \
isa; /* must be pointer-sized and use __ptrauth_objc_isa_pointer */ \
int volatile ref_cnt; \
int volatile xref_cnt
_os_object_s
扩展后完整的定义如下:
c
typedef struct _os_object_s {
const _os_object_vtable_s *__ptrauth_objc_isa_pointer os_obj_isa,
int volatile os_obj_ref_cnt;
int volatile os_obj_xref_cnt;
} _os_object_s;
上面代码中_os_object_vtable_s * os_obj_isa
从名字看,类似 OC 里面的isa
指针的作用。
2 _os_object_vtable_s
_os_object_vtable_s
的定义如下:
c
// 1. src/object_internal.h
typedef struct _os_object_vtable_s {
_OS_OBJECT_CLASS_HEADER();
} _os_object_vtable_s;
宏_OS_OBJECT_CLASS_HEADER
定义如下:
c
// 1. os/object_private.h
// Must match size of compiler-generated OBJC_CLASS structure rdar://10640168
#define _OS_OBJECT_CLASS_HEADER() \
void *_os_obj_objc_class_t[5]
注意上面宏定义的注释Must match size of compiler-generated OBJC_CLASS structure
,翻译过来就是数组_os_obj_objc_class_t
的大小和编译器产生的 OC 类大小一样。
假设有一个 OC 文件X.m
,里面只有一个类X
,使用clang -rewrite-objc
产生的cpp
文件内容如下:
c
extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_X __attribute__ ((used, section ("__DATA,__objc_data"))) = {
0, // &OBJC_METACLASS_$_X,
0, // &OBJC_CLASS_$_NSObject,
0, // (void *)&_objc_empty_cache,
0, // unused, was (void *)&_objc_empty_vtable,
&_OBJC_CLASS_RO_$_X,
};
上面代码初始化了一个结构体变量OBJC_CLASS_$_X
,这个变量的类型为struct _class_t
。
变量OBJC_CLASS_$_X
代表编译之后的类X
,而其类型struct _class_t
的定义为:
c
struct _class_t {
struct _class_t *isa;
struct _class_t *superclass;
void *cache;
void *vtable;
struct _class_ro_t *ro;
};
可以看到struct _class_t
的大小是5
个指针大小,正好和数组_os_obj_objc_class_t
的大小一样,因此_os_obj_objc_class_t
就是一个 OC 类的大小,后面可以看到这个变量的作用。
_os_object_vtalbe_s
扩展后的结果为:
c
typedef struct _os_object_vtable_s {
void *_os_obj_objc_class_t[5];
} _os_object_vtable_s;
将结构体_os_object_s
和_os_object_vtable_s
结合起来看,结构体_os_object_s
的内存布局为:
从上图可以看到,_os_object_s
的内存布局和 OC 对象十分相似。_os_object_s
类似 OC 对象,_os_obj_isa
类似 OC 对象中的isa
指针,_os_object_vtable_s
类似 OC 中的类对象_class_t
。
3 dispatch_object_s
dispatch_object_s
定义如下:
c
// 1. src/object_internal.h
struct dispatch_object_s {
_DISPATCH_OBJECT_HEADER(object);
};
宏_DISPATCH_OBJECT_HEADER
的定义如下:
c
// 1. src/object_internal.h
#define _DISPATCH_OBJECT_HEADER(x) \
_DISPATCH_OBJECT_HEADER_INTERNAL(x) \
struct dispatch_queue_s *do_targetq; \
void *do_ctxt; \
union { \
dispatch_function_t DISPATCH_FUNCTION_POINTER do_finalizer; \
void *do_introspection_ctxt; \
}
// 2. src/object_internal.h
#define _DISPATCH_OBJECT_HEADER(x) \
_DISPATCH_OBJECT_HEADER_INTERNAL(x) \
struct dispatch_queue_s *do_targetq; \
void *do_ctxt; \
union { \
dispatch_function_t DISPATCH_FUNCTION_POINTER do_finalizer; \
void *do_introspection_ctxt; \
}
// 3. src/object_internal.h
#define _DISPATCH_OBJECT_HEADER_INTERNAL(x) \
struct _os_object_s _as_os_obj[0]; \
OS_OBJECT_STRUCT_HEADER(dispatch_##x); \
struct dispatch_##x##_s *volatile do_next;
// 4. src/object_internal.h
#define OS_OBJECT_STRUCT_HEADER(x) \
_OS_OBJECT_HEADER(\
const struct x##_vtable_s *__ptrauth_objc_isa_pointer do_vtable, \
do_ref_cnt, \
do_xref_cnt)
注释3
处的宏_DISPATCH_OBJECT_HEADER_INTERNAL
定义中有一个0 长度的数组 _as_os_obj`。
0
长度的数组不占用内存空间,也就是说sizeof (_as_os_obj) == 0
,这里使用0
长度的数组是为了做一个标记,表示它后面的宏OS_OBJECT_STRUCT_HEADER
扩展出来的结果和结构体struct _os_object_s
一样。
dispatch_object_s
扩展之后的结果为:
c
struct dispatch_object_s {
// 前 3 项的内容和 struct _os_object_s 一样
const struct dispatch_object_vtable_s *__ptrauth_objc_isa_pointer do_vtable,
int volatile do_ref_cnt;
int volatile do_xref_cnt;
struct dispatch_object_s *volatile do_next;
struct dispatch_queue_s *do_targetq;
void *do_ctx;
union {
dispatch_function_t DISPATCH_FUNCTION_POINTER do_finalizer;
void *do_introspection_ctxt;
}
};
从扩展结果可以看到,dispatch_object_s
前3
项内容和struct _os_object_s
一样。
这里的一样
是指变量的类型以及变量的顺序一样,而不包括变量名。变量类型和顺序一致保证了两者在内存布局上一样,变量名和内存布局无关。
4 dispatch_object_vtable_s
dispatch_object_vtable_s
由宏DISPATCH_CLASS_DECL_BARE
定义:
c
// 1. src/object_internal.h
DISPATCH_CLASS_DECL_BARE(object, OBJECT);
DISPATCH_CLASS_DECL_BARE
的定义如下:
c
// 1. src/object_internal.h
#define DISPATCH_CLASS_DECL_BARE(name, cluster) \
OS_OBJECT_CLASS_DECL(dispatch_##name, \
DISPATCH_##cluster##_VTABLE_HEADER(dispatch_##name))
因此,宏DISPATCH_CLASS_DECL_BARE(name, OBJECT)
扩展为:
c
OS_OBJECT_CLASS_DECL(dispatch_object, DISPATCH_OBJECT_VTALBE_HEADER(dispatch_object))
宏DISPATCH_OBJECT_VTABLE_HEADER
的定义如下:
c
// 1. src/object_internal.h
#define DISPATCH_OBJECT_VTABLE_HEADER(x) \
unsigned long const do_type; \
void DISPATCH_VTABLE_ENTRY(do_dispose)(struct x##_s *, \
bool *allow_free); \
size_t DISPATCH_VTABLE_ENTRY(do_debug)(struct x##_s *, \
char *, size_t); \
void DISPATCH_VTABLE_ENTRY(do_invoke)(struct x##_s *, \
dispatch_invoke_context_t, dispatch_invoke_flags_t)
// 2. src/internal.h
#define DISPATCH_VTABLE_ENTRY(op) \
(* __ptrauth(ptrauth_key_process_independent_code, true, \
ptrauth_string_discriminator("dispatch." #op)) const op)
宏DISPATCH_VTALBE_ENTRY
中的__ptrauth
与PAC
指针认证有关,与 GCD 功能无关,扩展结果中可以剔除这些扩展,因此宏DISPATCH_OBJECT_VTABLE_HEADER
的扩展结果为:
c
unsigned const do_type;
void (* const do_dispose)(struct dispatch_object_s *, bool *allow_free);
size_t (* const do_debug)(struct dispatch_object_s *, char *, size_t);
void (* const do_invoke)(struct dispatch_object_s *, dispatch_invoke_context_t, dispatch_invoke_flags_t);
宏OS_OBJECT_CLASS_DECL
的定义如下:
c
// 1. src/object_internal.h
#define OS_OBJECT_CLASS_DECL(name, ...) \
struct name##_s; \
struct name##_extra_vtable_s { \
__VA_ARGS__; \
}; \
struct name##_vtable_s { \
_OS_OBJECT_CLASS_HEADER(); \
struct name##_extra_vtable_s _os_obj_vtable; \
}; \
OS_OBJECT_EXTRA_VTABLE_DECL(name, name) \
extern const struct name##_vtable_s OS_OBJECT_CLASS_SYMBOL(name) \
__asm__(OS_OBJC_CLASS_RAW_SYMBOL_NAME(OS_OBJECT_CLASS(name)))
// 2. os/object_private.h
#define OS_OBJECT_CLASS_SYMBOL(name) OS_##name##_class
// 3. os/object_private.h
#define OS_OBJC_CLASS_RAW_SYMBOL_NAME(name) "_OBJC_CLASS_$_" OS_STRINGIFY(name)
上面代码中__VA_ARGS__
就是宏DISPATCH_OBJECT_VTABLE_HEADER(dispatch_object)
扩展的结果。因此宏DISPATCH_CLASS_DECL_BARE(object, OBJECT)
扩展之后的结果为:
c
struct dispatch_object_s;
// 1. dispatch_object_extra_vtable_s
struct dispatch_object_extra_vtable_s {
unsigned const do_type;
void (* const do_dispose)(struct dispatch_object_s *, bool *allow_free);
size_t (* const do_debug)(struct dispatch_object_s *, char *, size_t);
void (* const do_invoke)(struct dispatch_object_s *, dispatch_invoke_context_t, dispatch_invoke_flags_t);
};
// 2. dispatch_object_vtable_s
struct dispatch_object_vtable_s {
void *_os_obj_objc_class_t[5];
struct dispatch_object_extra_vtable_s _os_obj_vtable;
};
// 3. OS_dispatch_object_class
extern const struct dispatch_object_vtable_s OS_dispatch_object_class __asm__("_OBJC_CLASS_$_OS_dispatch_object");
注释1
定义了结构体struct dispatch_object_extra_vtable_s
。它包含一个属性do_type
和3
个函数指针。
注释2
定义了结构体strcut dispatch_object_vtable_s
。从定义可以看到,这个结构体和struct _os_object_vtable_s
一样,同样包含了_os_obj_objc_class_t
。
注释3
声明了一个变量OS_dispatch_object_class
,它的类型是struct dispatch_object_vtable_s
。这个变量后面有一个__asm__
语法,在这里并非使用__asm__
内联汇编的功能,而是使用其另一个功能:为变量OS_dispatch_object_class
指定其在符号表中的符号名为_OBJC_CLASS_$_OS_dispatch_object
。相当于后续代码中引用OS_dispatch_object_class
的地方,编译后最终都是引用_OBJC_CLASS_$_OS_dispatch_object
。
从上面第2
部分_os_object_vtable_s
可以知道,_OBJC_CLASS_$_OS_dispatch_object
就是类OS_dispatch_object
编译之后对应类的变量名,或者更准确叫符号名。
在C
环境下,编译产生的符号名前面都会加一个前缀_
。仍以第2
部分_os_object_vtable_s
中类X
为例,使用clang -rewrite-objc
命令重写成C++
之后的完整定义为:
c++
extern "C" __declspec(dllexport) struct _class_t OBJC_CLASS_$_X __attribute__ ((used, section ("__DATA,__objc_data"))) = {
0, // &OBJC_METACLASS_$_X,
0, // &OBJC_CLASS_$_NSObject,
0, // (void *)&_objc_empty_cache,
0, // unused, was (void *)&_objc_empty_vtable,
&_OBJC_CLASS_RO_$_X,
};
上面最前面的extern "C"
就是指示编译器产生C
环境的符号,也就是最终OBJC_CLASS_$_X
编译产生的符号为_OBJC_CLASS_$_X
。
这就是_OBJC_CLASS_$_OS_dispatch_object
前面带有前缀_
的原因。
使用MachOView
查看iOS
的libdispatch.dylib
库符号表可以看到这个符号:
这里有个问题是_OBJC_CLASS_$_OS_dispatch_object
只有5
个指针的大小,而dispatch_object_vtable_s
占用的内存明显大于5
个指针,之所以能够这样做的原因在后续文章《GCD Inside: Queue 的创建》
解释。
结合dispatch_object_s
和dispatch_object_vtable_s
,dispatch_object_s
的内存布局如下所示:
从上图可以看到,结构体dispatch_object_s
开头部分和结构体_os_object_s
内存布局一样。换句话说,可以看成结构体dispatch_object_s
继承了结构体_os_object_s
。这是面向对象设计思想在C
环境下的实现。
结构体dispatch_object_vtable_s
开头布局和_os_object_vtable_s
一样,dispatch_object_vtable_s
可以看成是继承自_os_object_vtable_s
。
5 dispatch_queue_s
dispatch_queue_s
的定义如下:
c
// 1. src/queue_internal.h
struct dispatch_queue_s {
DISPATCH_QUEUE_CLASS_HEADER(queue, void *__dq_opaque1);
/* 32bit hole on LP64 */
} DISPATCH_ATOMIC64_ALIGN;
// 2. src/queue_internal.h
#define DISPATCH_QUEUE_CLASS_HEADER(x, __pointer_sized_field__) \
_DISPATCH_QUEUE_CLASS_HEADER(x, __pointer_sized_field__); \
/* LP64 global queue cacheline boundary */ \
unsigned long dq_serialnum; \
const char *dq_label; \
DISPATCH_UNION_LE(uint32_t volatile dq_atomic_flags, \
const uint16_t dq_width, \
const uint16_t __dq_opaque2 \
); \
dispatch_priority_t dq_priority; \
union { \
struct dispatch_queue_specific_head_s *dq_specific_head; \
struct dispatch_source_refs_s *ds_refs; \
struct dispatch_timer_source_refs_s *ds_timer_refs; \
struct dispatch_mach_recv_refs_s *dm_recv_refs; \
struct dispatch_channel_callbacks_s const *dch_callbacks; \
}; \
int volatile dq_sref_cnt
// 3. src/queue_internal.h
#define _DISPATCH_QUEUE_CLASS_HEADER(x, __pointer_sized_field__) \
DISPATCH_OBJECT_HEADER(x); \
__pointer_sized_field__; \
DISPATCH_UNION_LE(uint64_t volatile dq_state, \
dispatch_lock dq_state_lock, \
uint32_t dq_state_bits \
)
// 4. src/object_internal.h
#define DISPATCH_OBJECT_HEADER(x) \
struct dispatch_object_s _as_do[0]; \
_DISPATCH_OBJECT_HEADER(x)
扩展结果如下:
c
struct disaptch_queue_s {
// 头部是 _os_dispatch_object_s 内容
const struct dispatch_queue_vtable_s *__ptrauth_objc_isa_pointer do_vtable,
int volatile do_ref_cnt;
int volatile do_xref_cnt;
struct dispatch_queue_s *volatile do_next;
struct dispatch_queue_s *do_targetq;
void *do_ctx;
union {
dispatch_function_t DISPATCH_FUNCTION_POINTER do_finalizer;
void *do_introspection_ctxt;
};
void *__dq_opaque1;
union {
uint64_t volatile dq_state;
struct {
dispatch_lock dq_state_lock;
uint32_t dq_state_bits;
};
};
/* LP64 global queue cacheline boundary */
unsigned long dq_serialnum;
const char *dq_label;
union {
uint32_t volatile dq_atomic_flags;
struct {
const uint16_t dq_width;
const uint16_t __dq_opaque2;
};
};
dispatch_priority_t dq_priority;
union {
struct dispatch_queue_specific_head_s *dq_specific_head;
struct dispatch_source_refs_s *ds_refs;
struct dispatch_timer_source_refs_s *ds_timer_refs;
struct dispatch_mach_recv_refs_s *dm_recv_refs;
struct dispatch_channel_callbacks_s const *dch_callbacks;
};
int volatile dq_sref_cnt
}
从扩展结果可以看到,结构体dispatch_queue_s
头部的内存布局和结构体dispatch_object_s
一样。
6 dispatch_queue_vtable_s
disaptch_queue_vtable_s
由宏DISPATCH_CLASS_DECL
定义:
c
// 1. src/queue_internal.h
DISPATCH_CLASS_DECL(queue, QUEUE);
// 2. src/object_internal.h
#define DISPATCH_CLASS_DECL(name, cluster) \
_OS_OBJECT_DECL_PROTOCOL(dispatch_##name, dispatch_object) \
_OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(dispatch_##name, dispatch_##name) \
DISPATCH_CLASS_DECL_BARE(name, cluster)
具体的说,是构成DISPATCH_CLASS_DECL
宏的第3
个宏DISPATCH_CLASS_BARE
定义了dispatch_queue_vtable_s
,完整的扩展结果为:
c
struct dispatch_queue_s;
// 1. dispatch_queue_extra_vtable_s
struct dispatch_queue_extra_vtable_s {
unsigned long const do_type;
void (* const do_dispose)(struct dispatch_queue_s *, bool *allow_free);
size_t (* const do_debug)(struct dispatch_queue_s *, char *, size_t);
void (* const do_invoke)(struct dispatch_queue_s *, dispatch_invoke_context_t, dispatch_qos_t);
void (* const dq_activate)(dispatch_queue_class_t);
void (* const dq_wakeup)(dispatch_queue_class_t, dispatch_qos_t, dispatch_wakeup_flags_t);
void (* const dq_push)(dispatch_queue_class_t, dispatch_object_t, dispatch_qos_t);
};
// 2. dispatch_queue_vtable_s
struct dispatch_queue_vtable_s {
void *_os_obj_objc_class_t[5];
struct dispatch_queue_extra_vtable_s _os_obj_vtable;
}
// 3. OS_dispatch_queue_class
extern const struct dispatch_queue_vtable_s OS_dispatch_queue_class __asm__("_OBJC_CLASS_$_OS_dispatch_queue");
从扩展结果看,结构体dispatch_queue_vtable_s
和_os_dispatch_object_s
十分类似,只是结构体dispatch_queue_extra_vtable_s
多了3
个函数指针。
结合dispatch_queue_s
和dispatch_queue_vtable_s
,dispatch_queue_s
的内存布局如下所示:
从上面dispatch_queue_s
内存布局可以看到,结构体dispatch_queue_s
头部部分和结构体dispatch_object_s
一样,因此dispatch_queue_s
可以看成继承自dispatch_object_s
。
结构体dispatch_queue_vtable_s
头部和结构体dispatch_object_vtable_s
一样,因此dispatch_queue_vtable_s
可以看成继承自dispatch_object_vtable_s
。
结构体dispatch_queue_extra_vtable_s
头部和结构体dispatch_object_extra_vtable_s
,因此dispatch_queue_extra_vtable_s
可以看成继承自dispatch_object_extra_vtable_s
。
7 dispatch_lane_s
dispatch_lane_s
的定义如下:
c
// 1. src/queue_internal.h
typedef struct dispatch_lane_s {
DISPATCH_LANE_CLASS_HEADER(lane);
/* 32bit hole on LP64 */
} DISPATCH_ATOMIC64_ALIGN *dispatch_lane_t;
// 2. src/queue_internal.h
#define DISPATCH_LANE_CLASS_HEADER(x) \
struct dispatch_queue_s _as_dq[0]; \
DISPATCH_QUEUE_CLASS_HEADER(x, \
struct dispatch_object_s *volatile dq_items_tail); \
dispatch_unfair_lock_s dq_sidelock; \
struct dispatch_object_s *volatile dq_items_head; \
uint32_t dq_side_suspend_cnt
扩展之后的完整结果为:
c
typedef struct dispatch_lane_s {
// 头部是 dispatch_queue_s
const struct dispatch_lane_vtable_s *__ptrauth_objc_isa_pointer do_vtable;
int volatile do_ref_cnt;
int volatile do_xref_cnt;
struct dispatch_lane_s *volatile do_next;
struct dispatch_queue_s *do_targetq;
void *do_ctxt;
union {
dispatch_function_t DISPATCH_FUNCTION_POINTER do_finalizer;
void *do_introspection_ctxt;
};
struct dispatch_object_s *volatile dq_items_tail;
union {
uint64_t volatile dq_state;
struct {
dispatch_lock dq_state_lock;
uint32_t dq_state_bits;
};
);
/* LP64 global queue cacheline boundary */ \
unsigned long dq_serialnum; \
const char *dq_label; \
union {
uint32_t volatile dq_atomic_flags;
struct {
const uint16_t dq_width;
const uint16_t __dq_opaque2;
};
);
dispatch_priority_t dq_priority;
union {
struct dispatch_queue_specific_head_s *dq_specific_head;
struct dispatch_source_refs_s *ds_refs;
struct dispatch_timer_source_refs_s *ds_timer_refs;
struct dispatch_mach_recv_refs_s *dm_recv_refs;
struct dispatch_channel_callbacks_s const *dch_callbacks;
};
int volatile dq_sref_cnt;
dispatch_unfair_lock_s dq_sidelock;
struct dispatch_object_s *volatile dq_items_head;
uint32_t dq_side_suspend_cnt;
} *dispatch_lane_t;
从扩展结果可以看到,结构体dispatch_lane_s
头部内存布局和结构体dispatch_queue_s
一样。
同时,扩展结构定义了一个变量dispatch_lane_t
,其类型为dispatch_lane_s *
。
8 dispatch_lane_vtable_s
dispatch_lane_vtable_s
由宏DISPATCH_CLASS_DECL_BARE
定义:
c
// 1. src/queue_internal.h
DISPATCH_CLASS_DECL_BARE(lane, QUEUE);
dispatch_lane_vtable_s
由宏OS_OBJECT_SUBCLASS_DECL
定义,完整的展开结果为:
c
struct dispatch_lane_s;
// 1. dispatch_lane_extra_vtable_s
struct dispatch_lane_extra_vtable_s {
unsigned long const do_type;
void (* const do_dispose)(struct dispatch_lane_s * bool *allow_free);
size_t (* const do_debug)(struct dispatch_lane_s *, char *, size_t);
void (* const do_invoke)(struct dispatch_lane_s * dispatch_invoke_context_t, dispatch_invoke_flags_t);
void (* const dq_activate)(dispatch_queue_class_t);
void (* const dq_wakeup)(dispatch_queue_class_t, dispatch_qos_t, dispatch_wakeup_flags_t);
void (* const dq_push)(dispatch_queue_class_t, dispatch_object_t, dispatch_qos_t);
}
// 2. dispatch_lane_vtable_s
struct dispatch_lane_vtable_s {
void *_os_obj_objc_class_t[5];
struct dispatch_lane_extra_vtable_s _os_obj_vtable;
}
// 3. OS_dispatch_lane_class
extern const struct dispatch_lane_vtable_s OS_dispatch_lane_class __asm__("_OBJC_CLASS_$_OS_dispatch_lane")
从扩展结果可以看到,结构体dispatch_lane_vtable_s
和dispatch_queue_vtable_s
非常类似。
结合dispatch_lane_s
和dispatch_lane_vtable_s
,dispatch_lane_s
的内存布局如下所示:
从上图可以看到,结构体dispatch_lane_s
头部和结构体dispatch_queue_s
内存布局一样,可以看成dispatch_lane_s
继承自dispatch_queue_s
。
结构体dispatch_lane_vtable_s
内存布局完全和dispatch_queue_vtable_s
一样,因此dispatch_lane_vtable_s
可以看成继承自dispatch_object_vtalbe_s
。
结构体dispatch_lane_extra_vtable_s
内存布局完全和dispatch_queue_extra_vtable_s
一样,因此dispatch_lane_extra_vtable_s
可以看成是继承自dispatch_object_extra_vtable_s
。
9 dispatch_queue_class_t
dispatch_queue_class_t
的定义如下:
c
// 1. src/internal.h
// Dispatch queue cluster class: type for any dispatch_queue_t
typedef union {
struct dispatch_queue_s *_dq;
struct dispatch_workloop_s *_dwl;
struct dispatch_lane_s *_dl;
struct dispatch_queue_static_s *_dsq;
struct dispatch_queue_global_s *_dgq;
struct dispatch_queue_pthread_root_s *_dpq;
struct dispatch_source_s *_ds;
struct dispatch_channel_s *_dch;
struct dispatch_mach_s *_dm;
dispatch_lane_class_t _dlu;
#ifdef __OBJC__
id<OS_dispatch_queue> _objc_dq;
#endif
} dispatch_queue_class_t DISPATCH_TRANSPARENT_UNION;
可以看到,dispatch_queue_class_t
是一个指针联合体。
dispatch_queue_class_t
中的联合体成员dispatch_lane_class_t
的定义如下:
c
// Lane cluster class: type for all the queues that have a single head/tail pair
// 1. src/internal.h
typedef union {
struct dispatch_lane_s *_dl;
struct dispatch_queue_static_s *_dsq;
struct dispatch_queue_global_s *_dgq;
struct dispatch_queue_pthread_root_s *_dpq;
struct dispatch_source_s *_ds;
struct dispatch_channel_s *_dch;
struct dispatch_mach_s *_dm;
#ifdef __OBJC__
id<OS_dispatch_queue> _objc_dq; // unsafe cast for the sake of object.m
#endif
} dispatch_lane_class_t DISPATCH_TRANSPARENT_UNION;
可以看到,dispatch_lane_class_t
本身也是一个指针联合体。
10 总结
上文介绍结构体之间的继承关系如下图所示:
本文由mdnice多平台发布