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

AFNetworking 中 GCD 的使用(5)

作者: 老猫_2017 | 来源:发表于2020-01-15 14:09 被阅读0次

    GCD in AFNetworking 的使用

    AFImageDownloader 图片下载

    1. 创建队列,串行,并行
    - (instancetype)initWithSessionManager:(AFHTTPSessionManager *)sessionManager
                    downloadPrioritization:(AFImageDownloadPrioritization)downloadPrioritization
                    maximumActiveDownloads:(NSInteger)maximumActiveDownloads
                                imageCache:(id <AFImageRequestCache>)imageCache {
        if (self = [super init]) {
            ...
    
            NSString *name = [NSString stringWithFormat:@"com.alamofire.imagedownloader.synchronizationqueue-%@", [[NSUUID UUID] UUIDString]];
            self.synchronizationQueue = dispatch_queue_create([name cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_SERIAL);
    
            name = [NSString stringWithFormat:@"com.alamofire.imagedownloader.responsequeue-%@", [[NSUUID UUID] UUIDString]];
            self.responseQueue = dispatch_queue_create([name cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_CONCURRENT);
        }
    
        return self;
    }
    
    
    1. Dispatch_once
    + (instancetype)defaultInstance {
        static AFImageDownloader *sharedInstance = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            sharedInstance = [[self alloc] init];
        });
        return sharedInstance;
    }
    
    - (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
                                                      withReceiptID:(nonnull NSUUID *)receiptID
                                                            success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse  * _Nullable response, UIImage *responseObject))success
                                                            failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure {
        __block NSURLSessionDataTask *task = nil;
        dispatch_sync(self.synchronizationQueue, ^{
            if (URLIdentifier == nil) {
              ...
              // 结构返还主队列
              dispatch_async(dispatch_get_main_queue(), ^{
                  failure(request, nil, error);
              });
                        ...
                return;
            }
                    
            ...
           
            createdTask = [self.sessionManager
                           dataTaskWithRequest:request
                           uploadProgress:nil
                           downloadProgress:nil
                           completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                             // 异步并发操作
                               dispatch_async(self.responseQueue, ^{
                                   ...
    // 结果返还主队列
                                     dispatch_async(dispatch_get_main_queue(), ^{
       handler.failureBlock(request, (NSHTTPURLResponse *)response, error);
                                                   });
                    ...
                               
    }
    
    
    1. 同步操作,结果async to 主队列
    - (void)cancelTaskForImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt {
        dispatch_sync(self.synchronizationQueue, ^{
            ...
                if (handler.failureBlock) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        handler.failureBlock(imageDownloadReceipt.task.originalRequest, nil, error);
                    });
                }
                    ...
        });
    }
    
    1. 同步操作,保证线程安全
     - (AFImageDownloaderMergedTask *)safelyRemoveMergedTaskWithURLIdentifier:(NSString *)URLIdentifier {
        __block AFImageDownloaderMergedTask *mergedTask = nil;
        dispatch_sync(self.synchronizationQueue, ^{
            mergedTask = [self removeMergedTaskWithURLIdentifier:URLIdentifier];
        });
        return mergedTask;
    }
    
    - (void)safelyDecrementActiveTaskCount {
        dispatch_sync(self.synchronizationQueue, ^{
            if (self.activeRequestCount > 0) {
                self.activeRequestCount -= 1;
            }
        });
    }
    
    - (void)safelyStartNextTaskIfNecessary {
        dispatch_sync(self.synchronizationQueue, ^{
            if ([self isActiveRequestCountBelowMaximumLimit]) {
                while (self.queuedMergedTasks.count > 0) {
                    AFImageDownloaderMergedTask *mergedTask = [self dequeueMergedTask];
                    if (mergedTask.task.state == NSURLSessionTaskStateSuspended) {
                        [self startMergedTask:mergedTask];
                        break;
                    }
                }
            }
        });
    }
    
    - (AFImageDownloaderMergedTask *)safelyGetMergedTask:(NSString *)URLIdentifier {
        __block AFImageDownloaderMergedTask *mergedTask;
        dispatch_sync(self.synchronizationQueue, ^(){
            mergedTask = self.mergedTasks[URLIdentifier];
        });
        return mergedTask;
    }
    
    

    总结:

    1. 可以将 串行队列,与 dispatch_sync 结合,当作串行的概念,来保证数据安全, 避免竞争
    2. 返还结果,异步返还主队列
    3. 结果可以并发处理,场景时,串行开始,可能异步同时返还,增加处理效率。

    相关文章

      网友评论

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

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