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

Parser 中GCD的使用(9)

作者: 老猫_2017 | 来源:发表于2020-01-18 13:24 被阅读0次

    PFReachability.m 网络监控

    // 并行队列
    _synchronizationQueue = dispatch_queue_create("com.parse.reachability", DISPATCH_QUEUE_CONCURRENT);
    
    // 屏障独写
    - (void)addListener:(id<PFReachabilityListener>)listener {
        PFWeakValue *value = [PFWeakValue valueWithWeakObject:listener];
        dispatch_barrier_sync(_synchronizationQueue, ^{
            [self->_listenersArray addObject:value];
        });
    }
    
    // 屏障独写
    - (void)removeListener:(id<PFReachabilityListener>)listener {
        @weakify(listener);
        dispatch_barrier_sync(_synchronizationQueue, ^{
            @strongify(listener);
            [self->_listenersArray filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
                id weakObject = [evaluatedObject weakObject];
                return !(weakObject == nil || weakObject == listener);
            }]];
        });
    }
    
    - (void)removeAllListeners {
        dispatch_barrier_sync(_synchronizationQueue, ^{
            [self->_listenersArray removeAllObjects];
        });
    }
    // 异步并发执行
    - (void)_notifyAllListeners {
        @weakify(self);
        dispatch_async(_synchronizationQueue, ^{
            @strongify(self);
            PFReachabilityState state = [[self class] _reachabilityStateForFlags:self->_flags];
            for (PFWeakValue *value in self->_listenersArray) {
                [value.weakObject reachability:self didChangeReachabilityState:state];
            }
    
            dispatch_barrier_async(self->_synchronizationQueue, ^{
                [self->_listenersArray filterUsingPredicate:[NSPredicate predicateWithFormat:@"SELF.weakObject != nil"]];
            });
        });
    }
    
    // 异步并发独写
    - (void)setFlags:(SCNetworkReachabilityFlags)flags {
        dispatch_barrier_async(_synchronizationQueue, ^{
            self->_flags = flags;
            [self _notifyAllListeners];
        });
    }
    
    - (void)_startMonitoringReachabilityWithURL:(NSURL *)url {
        dispatch_barrier_async(_synchronizationQueue, ^{
            self->_networkReachability = SCNetworkReachabilityCreateWithName(NULL, url.host.UTF8String);
            if (self->_networkReachability != NULL) {
                // Set the initial flags
                SCNetworkReachabilityFlags flags;
                SCNetworkReachabilityGetFlags(self->_networkReachability, &flags);
                self.flags = flags;
    
                // Set up notification for changes in reachability.
                SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
                if (SCNetworkReachabilitySetCallback(self->_networkReachability, _reachabilityCallback, &context)) {
                    if (!SCNetworkReachabilitySetDispatchQueue(self->_networkReachability, self->_synchronizationQueue)) {
                        PFLogError(PFLoggingTagCommon, @"Unable to start listening for network connectivity status.");
                    }
                }
            }
        });
    }
    
    // 同步并发读
    - (SCNetworkReachabilityFlags)flags {
        __block SCNetworkReachabilityFlags flags;
        dispatch_sync(_synchronizationQueue, ^{
            flags = self->_flags;
        });
        return flags;
    }
    
    
    

    总结:并行队列,屏障独写;并发读。 Dispatch_barrier_sync & dispatch_barrier_async 等操作,比较多哦。

    BFTask+Private.m

    // dispatch_semaphore 等待异步线程执行结果
    - (id)waitForResult:(NSError **)error withMainThreadWarning:(BOOL)warningEnabled {
        ...
            dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
            [self continueWithBlock:^id(BFTask *task) {
                dispatch_semaphore_signal(semaphore);
                return nil;
            }];
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        ...
    }
    
    

    总结:异步等待执行结果, dipsatch_semaphore 可以实现这个效果。dispatch_group 也可以实现相同的效果。

    PFURLSession.m

    // 并发队列
    _delegatesAccessQueue = dispatch_queue_create("com.parse.urlSession.delegates", DISPATCH_QUEUE_CONCURRENT);
    
    // 同步并发读
    - (PFURLSessionDataTaskDelegate *)_taskDelegateForTask:(NSURLSessionTask *)task {
        __block PFURLSessionDataTaskDelegate *delegate = nil;
        dispatch_sync(_delegatesAccessQueue, ^{
            delegate = self->_delegatesDictionary[@(task.taskIdentifier)];
        });
        return delegate;
    }
    
    // 异步屏障写操作
    - (void)setDelegate:(PFURLSessionDataTaskDelegate *)delegate forDataTask:(NSURLSessionDataTask *)task {
        dispatch_barrier_async(_delegatesAccessQueue, ^{
            self->_delegatesDictionary[@(task.taskIdentifier)] = delegate;
        });
    }
    
    - (void)_removeDelegateForTaskWithIdentifier:(NSNumber *)identifier {
        dispatch_barrier_async(_delegatesAccessQueue, ^{
            [self->_delegatesDictionary removeObjectForKey:identifier];
        });
    }
    

    总结:并发读 ,屏障独写 dispatch_barrier_async & dispatch_barrier_sync, dispatch_sync 同步读。

    PFCoreManager.m

    总结:多串行队列,每个队列的意义明确,有不同的作用,保证数据安全。

    相关文章

      网友评论

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

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