美文网首页
Parser 中GCD的使用(5)

Parser 中GCD的使用(5)

作者: 老猫_2017 | 来源:发表于2020-01-17 16:41 被阅读0次

    PFEventuallyQueue 事件队列
    PFPinningEventuallyQueue 只是 同步线程,进行数据保护
    PFMemoryEventuallyQueue 内存线程,一样的

    // 串行队列,设置 special key, value, 进行队列验证。

    - (instancetype)initWithDataSource:(id<PFCommandRunnerProvider>)dataSource
                      maxAttemptsCount:(NSUInteger)attemptsCount
                         retryInterval:(NSTimeInterval)retryInterval {
        ...
        // Set up all the queues
        NSString *queueBaseLabel = [NSString stringWithFormat:@"com.parse.%@", NSStringFromClass([self class])];
    
        _synchronizationQueue = dispatch_queue_create([NSString stringWithFormat:@"%@.synchronization", queueBaseLabel].UTF8String,
                                                      DISPATCH_QUEUE_SERIAL);
        PFMarkDispatchQueue(_synchronizationQueue);
        _synchronizationExecutor = [BFExecutor executorWithDispatchQueue:_synchronizationQueue];
    
        _processingQueue = dispatch_queue_create([NSString stringWithFormat:@"%@.processing", queueBaseLabel].UTF8String,
                                                 DISPATCH_QUEUE_SERIAL);
        PFMarkDispatchQueue(_processingQueue);
    
        _processingQueueSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, _processingQueue);
        
        _commandEnqueueTaskQueue = [[PFTaskQueue alloc] init];
    
        ...
    
        return self;
    }
    
    

    下面是对 dispatch_source_type_add 的处理,

    // 处理 source 的队列
    _processingQueue = dispatch_queue_create([NSString stringWithFormat:@"%@.processing", queueBaseLabel].UTF8String,
                                                 DISPATCH_QUEUE_SERIAL);
    // source type add    
    _processingQueueSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, _processingQueue);
    
    // 触发调用 source event block
    dispatch_source_merge_data(_processingQueueSource, 1);
    
    // set event block
    - (void)start {
        dispatch_source_set_event_handler(_processingQueueSource, ^{
            [self _runCommands];
        });
        [self resume];
    }
    
    // 触发一次
    - (void)resume {
        if (self.running) {
            return;
        }
        self.running = YES;
        dispatch_resume(_processingQueueSource); // 启动
        dispatch_source_merge_data(_processingQueueSource, 1);
    }
    
    // 暂停
    - (void)pause {
        if (!self.running) {
            return;
        }
        self.running = NO;
        dispatch_suspend(_processingQueueSource);
    }
    
    // 关闭
    - (void)terminate {
        [self _stopMonitoringNetworkReachability];
        dispatch_source_cancel(_processingQueueSource);
    }
    

    通过 dispatch_source_merge_data(_processingQueueSource, 1); 进行异步调用,执行 event handler,在此处的作用,只是异步到 _processingQueue 进行处理数据,并没有数据上的计数,可以合并触发,不用那么及时的触发

    当了解这个规则后,可以更简洁的调用相同的异步操作

    在子线程中,同步等待 retryInterval * NSEC_PER_SEC , dispatch_semaphore 的作用相当于阻塞当前线程等待一定时间

                                    __block dispatch_semaphore_t semaphore = NULL;
                    dispatch_sync(_synchronizationQueue, ^{
                        self->_retryingSemaphore = dispatch_semaphore_create(0);
                        semaphore = self->_retryingSemaphore;
                    });
    
                    dispatch_time_t timeoutTime = dispatch_time(DISPATCH_TIME_NOW,
                                                                (int64_t)(self.retryInterval * NSEC_PER_SEC));
    
                    long waitResult = dispatch_semaphore_wait(semaphore, timeoutTime);
                    dispatch_sync(_synchronizationQueue, ^{
                        self->_retryingSemaphore = NULL;
                    });
    
    // 网络重新连接,肯定是不,重新开始
        if (connected) {
            dispatch_async(_synchronizationQueue, ^{
                if (self->_retryingSemaphore) {
                    dispatch_semaphore_signal(self->_retryingSemaphore);
                }
            });
        }
    
    

    总结:使用 dispatch_semaphore 进行队列阻塞。

    相关文章

      网友评论

          本文标题:Parser 中GCD的使用(5)

          本文链接:https://www.haomeiwen.com/subject/thaczctx.html