GCD Inside: 数据结构(二)

更多文章关注公众号【白羊哈哈】

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_s3项内容和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中的__ptrauthPAC指针认证有关,与 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_type3个函数指针。

注释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查看iOSlibdispatch.dylib库符号表可以看到这个符号:

这里有个问题是_OBJC_CLASS_$_OS_dispatch_object只有5个指针的大小,而dispatch_object_vtable_s占用的内存明显大于5个指针,之所以能够这样做的原因在后续文章《GCD Inside: Queue 的创建》解释。

结合dispatch_object_sdispatch_object_vtable_sdispatch_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_sdispatch_queue_vtable_sdispatch_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_sdispatch_queue_vtable_s非常类似。

结合dispatch_lane_sdispatch_lane_vtable_sdispatch_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多平台发布

相关推荐
若水无华1 天前
fiddler 配置ios手机代理调试
ios·智能手机·fiddler
Aress"1 天前
【ios越狱包安装失败?uniapp导出ipa文件如何安装到苹果手机】苹果IOS直接安装IPA文件
ios·uni-app·ipa安装
Jouzzy2 天前
【iOS安全】Dopamine越狱 iPhone X iOS 16.6 (20G75) | 解决Jailbreak failed with error
安全·ios·iphone
瓜子三百克2 天前
采用sherpa-onnx 实现 ios语音唤起的调研
macos·ios·cocoa
左钦杨2 天前
IOS CSS3 right transformX 动画卡顿 回弹
前端·ios·css3
努力成为包租婆2 天前
SDK does not contain ‘libarclite‘ at the path
ios
安和昂2 天前
【iOS】Tagged Pointer
macos·ios·cocoa
I烟雨云渊T3 天前
iOS 阅后即焚功能的实现
macos·ios·cocoa
struggle20253 天前
适用于 iOS 的 开源Ultralytics YOLO:应用程序和 Swift 软件包,用于在您自己的 iOS 应用程序中运行 YOLO
yolo·ios·开源·app·swift
Unlimitedz3 天前
iOS视频编码详细步骤(视频编码器,基于 VideoToolbox,支持硬件编码 H264/H265)
ios·音视频