Parser 中GCD的使用(9)
2020-01-18 本文已影响0人
老猫_2017
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
总结:多串行队列,每个队列的意义明确,有不同的作用,保证数据安全。