Unh*_*lig 0 grand-central-dispatch
有一个用户想知道这意味着什么的帖子:
@property (nonatomic, strong) __attribute__((NSObject)) dispatch_queue_t captureQueue;
Run Code Online (Sandbox Code Playgroud)
他应该得到一些错误,我想我会谷歌,因为我也感兴趣.
有一件事导致了另一件事,这引出了我的问题:
实际的类型是dispatch_queue_t什么?
我也做了一些谷歌搜索,过去在SO上发现了2个问题.一个基本上集中在后缀部分,即_t关于POSIX和C的历史,所以它没有回答我的问题.
另一个是接近的,但接受的答案基本上是说它是一个typedef,没有人应该知道.它是一个依赖于系统的类型,必须处理位.
这对我来说不是一个好奇的人.而且我认为必须有人知道或有人知道比我更好,所以我的问题在这里.
如果确实没有人知道,那么即使是一个答案,至少告诉我这个机制如何以抽象的方式工作以及如何确定其类型(BTW,运行时或编译时?)根据不同的位不同的操作系统仍然足以满足我.
我也只是看着queue.h和block.m,我发现了什么是只有这个小一条信息:
typedef struct dispatch_queue_s *dispatch_queue_t;
Run Code Online (Sandbox Code Playgroud)
在queue.h,我看到了这个:
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
#endif
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
extern struct dispatch_queue_s _dispatch_main_q;
#define dispatch_get_main_queue() (&_dispatch_main_q)
Run Code Online (Sandbox Code Playgroud)
这超出了我的范围.我希望非常了解GCD的人可以分享一些关于此的知识.
TL; DR版本:
如果您的好奇只是想知道这些字段是什么struct dispatch_queue_s,您可以在此文件中自己阅读,但作为API的使用者/用户,您永远不需要知道这些信息才能使用它.因为你永远不需要知道,并且因为该结构中的字段不是公共API的一部分,如果你使用这些知识(除了你自己的启发和娱乐),你就是在为自己设置麻烦.
长版:
让我们看看我是否可以在这里逐一进行:
有一个用户想知道这意味着什么的帖子:
@property(非原子,强)属性((NSObject))dispatch_queue_t captureQueue; 他应该得到一些错误,我想我会谷歌,因为我也感兴趣.
有一件事导致了另一件事,这引出了我的问题:
该ARC文档这样说:
应用
__attribute__((NSObject))不属于可保留对象指针类型的属性具有与ARC之外相同的行为:它要求属性类型为某种指针,并允许使用除assign之外的修饰符.这些修饰符只影响合成的吸气剂和固定剂; 对ivar的直接访问(即使合成)仍然具有原始语义,并且在重新分配期间不会自动释放ivar中的值.
既然你没有说出问题是什么,那么我很难解决它们.我自己从不使用它,从阅读文档,听起来不推荐.我当然从来没有需要这个在一个持有a的属性上获得强大的ARC语义dispatch_queue_t.
接下来的事情:
dispatch_queue_t的实际类型是什么?
我也做了一些谷歌搜索,过去在SO上发现了2个问题.一个基本上关注后缀部分,即_t,关于POSIX和C的历史,所以它没有回答我的问题.
好的,_t后缀是一个"保留命名空间",当POSIX.1在POSIX.1中时POSIX"调用dibs".所有这些意味着,如果您设计使用_t类型的后缀,POSIX将不会保证更新版本的POSIX规范也不会声明具有可能破坏您的代码的同名的类型.在实践中,您可以继续使用后缀,如果您喜欢它,或者是否有助于您更好地理解代码,或者使其看起来更像POSIX-y,或者其他什么.或者不要使用它.这是你的选择.
另一个是接近的,但接受的答案基本上是说它是一个typedef,没有人应该知道.它是一个依赖于系统的类型,必须处理位.
并不是"没有人应该知道"更多的是"这个API的消费者被警告不要关心" - 将这种类型的指针视为不透明.这是typedef:
typedef struct dispatch_queue_s *dispatch_queue_t;
Run Code Online (Sandbox Code Playgroud)
为了剖析这一点,这意味着它dispatch_queue_t是一个指向前向声明的结构的指针dispatch_queue_s.API的消费者不需要知道该结构的布局,因此声明但未定义的事实不会导致编译器进行barf.你可以使用你的声明可见的东西,但是它的定义并不是所有的时间(任何时候你都像printf或者之类的那样调用库函数NSLog.)通过类比,如果我给你一个街道地址(一个指针)来邮寄一个在那封信中,你会假设在那个地址有一座建筑物(指向的东西),但你不需要知道建筑物是房子,办公楼,还是其他任何东西,如果你有唯一的互动与它通过其地址发送和接收邮件.
就像_t,这是一个面向未来的实践.如果将dispatch_queue_t(它是一个指针)视为不透明,并且Apple更改struct dispatch_queue_s了未来版本的内部结构,则代码不会中断.你从未对它的内部做出任何假设,因为你没有这些信息.
这对我来说不是一个好奇的人.而且我认为必须有人知道或有人知道比我更好,所以我的问题在这里.
libdispatch是开源的,所以你可以去阅读几乎所有有关它的知识.同样,并不是说你"不应该知道",而是为了使用它而不需要知道它.如果你真的想知道,那就......他们说,"使用来源,卢克." 切入正题?如果您的好奇心是知道这些字段是什么struct dispatch_queue_s,您可以在此文件中自己阅读,但作为API的使用者,您将永远不需要知道此信息才能使用GCD.FWIW,GCD源可能有点难以解析(很多分支预测暗示所有地方的东西,很多#defines等等)所以阅读它可能会或可能不会真正帮助你理解你想要理解的东西.
如果确实没有人知道,那么即使是一个答案,至少告诉我这个机制如何以抽象的方式工作以及如何确定其类型(BTW,运行时或编译时?)根据不同的位不同的操作系统仍然足以满足我.
我希望我能够帮助解决这个问题.FWIW,这些东西在编译时都知道每个组件的各种"编译时间".struct dispatch_queue_s当时已知的布局libdispatch由Apple编译并随操作系统一起提供.当你的程序编译时,它将知道它需要知道的一切,这仅限于"有一个结构,在其他地方定义,被调用dispatch_queue_s,我将使用不透明指针与该结构进行交互."
最后:
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
#endif
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
extern struct dispatch_queue_s _dispatch_main_q;
#define dispatch_get_main_queue() (&_dispatch_main_q)
Run Code Online (Sandbox Code Playgroud)
在您理解不透明类型的过程中,此代码主要是一个红色的鲱鱼.第一部分是声明函数dispatch_async,第二部分是播放一个小技巧,说明在另一个库(extern)中有一个公共全局变量,struct dispatch_queue_s其符号是类型_dispatch_main_q,并且每当预处理器看到字符串时,dispatch_get_main_queue()它应该替换它(&_dispatch_main_q).当人们想要获得指向主队列的指针时,这节省了函数调用的开销.它可以很容易地声明为完全不透明的函数,如:dispatch_queue_t dispatch_get_main_queue(void);在库中定义如下:
dispatch_queue_t dispatch_get_main_queue()
{
return &_dispatch_main_q;
}
Run Code Online (Sandbox Code Playgroud)
......虽然表现不佳.希望这很有帮助.
| 归档时间: |
|
| 查看次数: |
1032 次 |
| 最近记录: |