网络请求中,避免多个block错乱

 * author:conowen@大钟                                                                                                                          
 * E-mail:[email protected]      

1、block的定义

关于block的定义可以参考我之前的一篇文章

2、多个Block导致的问题

假设这么一个场景,需要进行多次的socket请求;发送网络请求A,然后继续发送网络请求B�,每个网络请求会带有Block作为返回的结果(这连个网络请求的Block类型都是一样的),但是可能由于各种网络原因,网络请求B可能先通过Block返回结果,而网络请求A最后才通过Block返回结果,这时候就导致Block错乱,不知道这个Block是哪个请求返回的。

3、解决思路

假设网络请求如下

- (void)sendCommand:(uint32_t)requestCode
               data:(nullable NSData *)data
               flag:(uint32_t)flag
        receiveData:(void(^ _Nullable)(__kindof NSData *__nonnull receiveCmdPackage))receiveCmdDataBlock
     receiveTimeOut:(NSTimeInterval) receiveTimeOut
receiveTimeOutBlock:(void(^ _Nullable)())receiveCmdTimeOutBlock;

发起网络请求时,附带一个随机数tag作为参数发送到服务器,然后新建一个保存Block的Object。

key = tag;
value = block;

如下代码:

    BlockObject *blockObject = [BlockObject new];
    blockObject.receiveCmdTimeOutBlock = receiveCmdTimeOutBlock;
    blockObject.receiveCmdDataBlock = receiveCmdDataBlock;
    blockObject.CMD = requestCode;
    [[BlockHelper sharedInstance] addRequestItem:blockObject];

服务器接收到刚刚作为参数传过来的tag,网络返回数据时同时带有作为参数的tag,这样就可以通过tag在刚刚的object队列里面取出block,然后回调block即可。

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
  BlockObject *request = [[BlockHelper sharedInstance] getRequestItemWithCMD:self.readCmdSocketCmdId seq:self.readCmdSocketSeq];
 if (request.receiveCmdDataBlock) {
    request.receiveCmdDataBlock(readData);
 }
  if ((self.readCmdSocketFlag & 0x02) == 0) {
     [[BlockHelper sharedInstance] removeRequestItem:request.tag];
}

你可能感兴趣的:(网络请求中,避免多个block错乱)