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

相关推荐
Jinkey4 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
程序猿看视界10 小时前
如何在 UniApp 中实现 iOS 版本更新检测
ios·uniapp·版本更新
dr李四维14 小时前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
️ 邪神14 小时前
【Android、IOS、Flutter、鸿蒙、ReactNative 】自定义View
flutter·ios·鸿蒙·reactnative·anroid
比格丽巴格丽抱1 天前
flutter项目苹果编译运行打包上线
flutter·ios
网络安全-老纪1 天前
iOS应用网络安全之HTTPS
web安全·ios·https
1024小神1 天前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
lzhdim1 天前
iPhone 17 Air看点汇总:薄至6mm 刷新苹果轻薄纪录
ios·iphone
安和昂1 天前
【iOS】知乎日报第四周总结
ios
麦田里的守望者江1 天前
KMP 中的 expect 和 actual 声明
android·ios·kotlin