第44月第20天 The dispatch_queue_set_specific() and dispatch_get_specific() functions take a "void *key" parameter.

1.

76     //socket队列的标识key
77     void *IsOnSocketQueueOrTargetQueueKey;
 88           void *nonNullUnusedPointer = (__bridge void *)self;
 89 
 90         //dispatch_queue_set_specific给当前队里加一个标识 dispatch_get_specific当前线程取出这个标识,判断是不是在这个队列
 91         //这个key的值其实就是一个一级指针的地址  ,第三个参数把自己传过去了,上下文对象?第4个参数,为销毁的时候用的,可以指定一个函数
 92           dispatch_queue_set_specific(socketQueue, IsOnSocketQueueOrTargetQueueKey, nonNullUnusedPointer, NULL);


3.生成了一个socketQueue,这个queue是串行的,接下来我们看代码就会知道它贯穿于这个类的所有地方。所有对socket以及一些内部数据的相关操作,都需要在这个串行queue中进行。这样使得整个类没有加一个锁,就保证了整个类的线程安全。

  • 接着我们回到正题上,我们定义了一个Block,所有的连接操作都被包裹在这个Block中。我们做了如下判断:
  //在socketQueue中执行这个Block
  if (dispatch_get_specific(IsOnSocketQueueOrTargetQueueKey))
      block();
  //否则同步的调起这个queue去执行
  else
      dispatch_sync(socketQueue, block);

保证这个连接操作一定是在我们的socketQueue中,而且还是以串行同步的形式去执行,规避了线程安全的问题。



https://blog.csdn.net/weixin_30402343/article/details/95261039?fps=1&locationNum=2
原文地址:https://www.cnblogs.com/javastart/p/12923228.html