GCD 中的类型
在 GCD 中涉及的变量类型有:
dispatch_block_t
、dispatch_function_t
、dispatch_time_t
、
dispatch_object_t
、dispatch_queue_t
、dispatch_group_t
等。
理解这些变量的定义有助于我们理解 GCD 的使用方式以及实现逻辑。
由 dispatch_block_t
的定义 typedef void (^dispatch_block_t)(void);
可知,其就是一个没有参数和返回值的 block 任务代码块。
由 dispatch_function_t
的定义 typedef void (*dispatch_function_t)(void *_Nullable);
可知,其是一个函数指针,所指向的函数没有返回值并且包含一个可为空的指针参数。
由 dispatch_time_t
的定义 typedef uint64_t dispatch_time_t;
可知,其是一个无符号整型 64 位的数值,用来表示时间。
这几个类型的定义较为简单,但是要理解其他类型的定义,要先理解 GCD 中的一些宏。
GCD 中的宏
当对象可用且为 OC 语言时,有如下定义:
#define DISPATCH_DECL(name) OS_OBJECT_DECL_SUBCLASS(name, dispatch_object)
#define OS_OBJECT_DECL_SUBCLASS(name, super) \
OS_OBJECT_DECL_IMPL(name, <OS_OBJECT_CLASS(super)>)
#define OS_OBJECT_CLASS(name) OS_##name
#define OS_OBJECT_DECL_IMPL(name, ...) \
OS_OBJECT_DECL_PROTOCOL(name, __VA_ARGS__) \
typedef NSObject<OS_OBJECT_CLASS(name)> \
* OS_OBJC_INDEPENDENT_CLASS name##_t
#define OS_OBJECT_DECL_PROTOCOL(name, ...) \
@protocol OS_OBJECT_CLASS(name) __VA_ARGS__ \
@end
#if __has_attribute(objc_independent_class)
#define OS_OBJC_INDEPENDENT_CLASS __attribute__((objc_independent_class))
#endif // __has_attribute(objc_independent_class)
#ifndef OS_OBJC_INDEPENDENT_CLASS
#define OS_OBJC_INDEPENDENT_CLASS
#endif
#define OS_OBJECT_DECL_CLASS(name) OS_OBJECT_DECL(name)
#define OS_OBJECT_DECL(name, ...) \
OS_OBJECT_DECL_IMPL(name, <NSObject>)
DISPATCH_DECL(dispatch_group);
现在来一步一步将宏
DISPATCH_DECL(dispatch_group);
替换,如下:
DISPATCH_DECL(dispatch_group);
=>
OS_OBJECT_DECL_SUBCLASS(dispatch_group, dispatch_object);
=>
OS_OBJECT_DECL_IMPL(dispatch_group, <OS_OBJECT_CLASS(dispatch_object)>);
=>
OS_OBJECT_DECL_PROTOCOL(dispatch_group, <OS_dispatch_object>) \
typedef NSObject<OS_OBJECT_CLASS(dispatch_group)> \
* OS_OBJC_INDEPENDENT_CLASS dispatch_group_t;
=>
@protocol OS_OBJECT_CLASS(dispatch_group) <OS_dispatch_object> @end \
typedef NSObject<OS_dispatch_group> \
* dispatch_group_t;
=>
@protocol OS_dispatch_group <OS_dispatch_object> @end \
typedef NSObject<OS_dispatch_group> \
* dispatch_group_t;
整理得到:
@protocol OS_dispatch_group <OS_dispatch_object>
@end
typedef NSObject<OS_dispatch_group> * dispatch_group_t;
结果得到一个继承了 OS_dispatch_object
协议的 OS_dispatch_group
协议,并且为遵循该协议的实例对象类型定义了一个 dispatch_group_t
别名,那么协议 OS_dispatch_object
又是从何而来呢,接着去找它的定义。
OS_OBJECT_DECL_CLASS(dispatch_object);
现在来一步一步将宏
OS_OBJECT_DECL_CLASS(dispatch_object);
替换,如下:
OS_OBJECT_DECL_CLASS(dispatch_object);
=>
OS_OBJECT_DECL(dispatch_object);
=>
OS_OBJECT_DECL_IMPL(dispatch_object, <NSObject>);
=>
OS_OBJECT_DECL_PROTOCOL(dispatch_object, <NSObject>) \
typedef NSObject<OS_OBJECT_CLASS(dispatch_object)> \
* OS_OBJC_INDEPENDENT_CLASS dispatch_object_t;
=>
@protocol OS_OBJECT_CLASS(dispatch_object) <NSObject> @end \
typedef NSObject<OS_dispatch_object> \
* dispatch_object_t;
=>
@protocol OS_dispatch_object <NSObject> @end \
typedef NSObject<OS_dispatch_object> \
* dispatch_object_t;
最终整理得到:
@protocol OS_dispatch_object <NSObject>
@end
typedef NSObject<OS_dispatch_object> * dispatch_object_t;
可知,定义了一个继承 NSObject
协议的 OS_dispatch_object
协议,并且为遵循该协议的实例对象类型定义了一个别名 dispatch_object_t
。
综上所述,宏
OS_OBJECT_DECL_CLASS(name)
会定义一个继承了NSObject
协议的协议,协议的名称为name
添加前缀OS_
,并且定义一个表示遵循该协议的实例对象类型的别名,名称为name
添加后缀_t
。
同样的,宏
DISPATCH_DECL(name)
的功能类似,但是其所定义的协议继承至OS_dispatch_object
协议。
另外,由 #define DISPATCH_DECL_SUBCLASS(name, base) OS_OBJECT_DECL_SUBCLASS(name, base)
可知,还可以在定义一个协议时,指定其所继承的协议,但是在使用时,要保证指定的 base
协议是已经定义过的。
如此,可以轻松得到如下结果:
DISPATCH_DECL(dispatch_queue);
=>
@protocol OS_dispatch_queue <OS_dispatch_object>
@end
typedef NSObject<OS_dispatch_queue> * dispatch_queue_t;
DISPATCH_DECL_SUBCLASS(dispatch_queue_global, dispatch_queue);
=>
@protocol OS_dispatch_queue_global <OS_dispatch_queue>
@end
typedef NSObject<OS_dispatch_queue_global> * dispatch_queue_global_t;
DISPATCH_DECL_SUBCLASS(dispatch_queue_serial, dispatch_queue);
=>
@protocol OS_dispatch_queue_serial <OS_dispatch_queue>
@end
typedef NSObject<OS_dispatch_queue_serial> * dispatch_queue_serial_t;
DISPATCH_DECL_SUBCLASS(dispatch_queue_main, dispatch_queue_serial);
=>
@protocol OS_dispatch_queue_main <OS_dispatch_queue_serial>
@end
typedef NSObject<OS_dispatch_queue_main> * dispatch_queue_main_t;
DISPATCH_DECL_SUBCLASS(dispatch_queue_concurrent, dispatch_queue);
=>
@protocol OS_dispatch_queue_concurrent <OS_dispatch_queue>
@end
typedef NSObject<OS_dispatch_queue_concurrent> * dispatch_queue_concurrent_t;
DISPATCH_DECL(dispatch_queue_attr);
=>
@protocol OS_dispatch_queue_attr <NSObject>
@end
typedef NSObject<OS_dispatch_queue_attr> * dispatch_queue_attr_t;