题目如下:下面代码输出结果是什么?是YES还是NO还是编译出错?
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_queue_t queue = dispatch_get_main_queue();
BOOL isEqual = [queue isKindOfClass:[NSObject class]];
NSLog(@"isEqual=%d", isEqual);
}
在回答这个问题之前,首先考虑2个问题:
1. 变量queue被声明的类型是什么?
2. queue的真实类型是什么?
1.queue被声明的类型是什么?
很明显是 dispatch_queue_t ,但dispatch_queue_t又是什么呢?
点进去看一下会定位在这行代码里,DISPATCH_DECL(dispatch_queue)里;DISPATCH_DECL的定义如下 #define DISPATCH_DECL(name) OS_OBJECT_DECL_SUBCLASS(name, dispatch_object),则OS_OBJECT_DECL_SUBCLASS是什么就点进不去了,不过由于GCD是开源的,通过源码得到的宏定义如下:
dispatch_queue_t => ISPATCH_DECL(dispatch_queue);
#define DISPATCH_DECL(name) OS_OBJECT_DECL_SUBCLASS(name, dispatch_object)
#define OS_OBJECT_DECL_SUBCLASS(name, super) \
OS_OBJECT_DECL_IMPL(name, NSObject, <OS_OBJECT_CLASS(super)>)
#define OS_OBJECT_DECL_IMPL(name, adhere, ...) \
OS_OBJECT_DECL_PROTOCOL(name, __VA_ARGS__) \
typedef adhere<OS_OBJECT_CLASS(name)> \
* OS_OBJC_INDEPENDENT_CLASS name##_t
#define OS_OBJECT_DECL_PROTOCOL(name, ...) \
@protocol OS_OBJECT_CLASS(name) __VA_ARGS__ \
@end
#define OS_OBJECT_CLASS(name) OS_##name
把DISPATCH_DECL(dispatch_queue)展开之后可以得到
OS_OBJECT_DECL_SUBCLASS(dispatch_queue, dispatch_object)
OS_OBJECT_DECL_IMPL(dispatch_queue, NSObject, <OS_OBJECT_CLASS(dispatch_object)>)
@protocol OS_dispatch_queue <OS_dispatch_object>
@end
typedef NSObject<OS_dispatch_queue> * dispatch_queue_t
通过上面的代码,可以看到dispatch_queue_t是NSObject<OS_dispatch_queue> *别名,可以得出queue被声明的类型是NSObject,因此上面的代码是可以被编译通过的。
2. queue的真实类型是什么?
debug代码,得到真实类型如下:是OS_dispatch_queue_main,是NSObject的子类,到此已经可以上面的打印为true
3. Why,主队列为何是一个对象
这时,又产生了一个新的疑问,主队列是一个结构体,这里为什么会显示是一个类呢?那么看一下主队列结构体里的内容
struct dispatch_queue_static_s _dispatch_main_q = {
DISPATCH_GLOBAL_OBJECT_HEADER(queue_main),
#if !DISPATCH_USE_RESOLVERS
.do_targetq = _dispatch_get_default_queue(true),
#endif
.dq_state = DISPATCH_QUEUE_STATE_INIT_VALUE(1) |
DISPATCH_QUEUE_ROLE_BASE_ANON,
.dq_label = "com.apple.main-thread",
.dq_atomic_flags = DQF_THREAD_BOUND | DQF_WIDTH(1),
.dq_serialnum = 1,
};
可以看到结构体内部最上面是一个宏定义,完全展开后如下
struct dispatch_queue_static_s _dispatch_main_q = {
.do_vtable = &OS_dispatch_queue_main_class,
.do_ref_cnt = Int_Max,
.do_xref_cnt = Int_Max,
#if !DISPATCH_USE_RESOLVERS
.do_targetq = _dispatch_get_default_queue(true),
#endif
.dq_state = DISPATCH_QUEUE_STATE_INIT_VALUE(1) |
DISPATCH_QUEUE_ROLE_BASE_ANON,
.dq_label = "com.apple.main-thread",
.dq_atomic_flags = DQF_THREAD_BOUND | DQF_WIDTH(1),
.dq_serialnum = 1,
};
看到了第一个字段指向了OS_dispatch_queue_main_class,猜测是OS_dispatch_queue_main的class对象,若一个结构体第一个字段指向了某个类对象,则会认为这个结构体是此类的实例,验证如下:
若有错误,欢迎指出,如果对你有帮助,希望能得到你的点赞