zoukankan      html  css  js  c++  java
  • 第25月第26天 dispatch_group_t dispatch_semaphore_t

    1.

    dispatch_group_enter(group);

    dispatch_group_leave(group);

     dispatch_group_notify(group1, queue1,block);

    在这种组合下,根据任务是同步、异步又分为两种,这两种组合的执行代码与运行结果如下:

    第一种:同步任务时

    复制代码
     dispatch_queue_t queue2 = dispatch_queue_create("dispatchGroupMethod2.queue2", DISPATCH_QUEUE_CONCURRENT);
        dispatch_group_t group2 = dispatch_group_create();
        
    
        dispatch_group_enter(group2);
        dispatch_sync(queue2, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-同步任务执行-:%ld",@"任务1",(long)i);
                
            }
            dispatch_group_leave(group2);
        });
        
    
        
        dispatch_group_enter(group2);
        dispatch_sync(queue2, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-同步任务执行-:%ld",@"任务2",(long)i);
                
            }
            dispatch_group_leave(group2);
        });
        
    //    //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
    //    dispatch_group_wait(group2, DISPATCH_TIME_FOREVER);
        
        //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
        dispatch_group_notify(group2, queue2, ^{
            NSLog(@"Method2-全部任务执行完成");
        });
    复制代码

    同步任务执行结果:

    第二种:异步任务时

    复制代码
       dispatch_queue_t queue2 = dispatch_queue_create("dispatchGroupMethod2.queue2", DISPATCH_QUEUE_CONCURRENT);
        dispatch_group_t group2 = dispatch_group_create();
        
    
        dispatch_group_enter(group2);
        dispatch_async(queue2, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-异步任务执行-:%ld",@"任务1",(long)i);
                
            }
            dispatch_group_leave(group2);
        });
        
    
        
        dispatch_group_enter(group2);
        dispatch_async(queue2, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-异步任务执行-:%ld",@"任务2",(long)i);
                
            }
            dispatch_group_leave(group2);
        });
        
    //    //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
    //    dispatch_group_wait(group2, DISPATCH_TIME_FOREVER);
        
        //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
        dispatch_group_notify(group2, queue2, ^{
            NSLog(@"Method2-全部任务执行完成");
        });
    复制代码

    异步任务执行结果:

    https://www.cnblogs.com/zhou--fei/p/6747938.html

    2.

    创建一个信号量,作为全局变量。
    并初始化,信号量为0

    dispatch_semaphore_t semaphore;
    semaphore = dispatch_semaphore_create(0);
    

    创建一个dispatch_group_t,开启两个组异步线程(dispatch_group_async),分别执行两个网络请求。
    一个组通知线程(dispatch_group_notify),用于接收前面两个线程的结果。

    dispatch_group_t group = dispatch_group_create();
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_group_async(group, queue, ^{
            [weakSelf loadRelationDetail];//请求1
        });
        dispatch_group_async(group, queue, ^{
            [weakSelf loadRelationReward];//请求2
        });
        dispatch_group_notify(group, queue, ^{
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            //合并(此处是数据处理,你可根据具体业务需求进行处理)
            NSMutableArray *arr = [NSMutableArray array];
            [arr addObjectsFromArray:weakSelf.arr1];
            [arr addObjectsFromArray:weakSelf.arr2];
            //排序
            if (arr.count > 1) {
                weakSelf.sumArr = [arr sortedArrayUsingComparator:^NSComparisonResult(ZHShareItem *obj1, ZHShareItem *obj2) {
                    return [obj1.createTime compare:obj2.createTime];
                }];
            }else{
                weakSelf.sumArr = arr;
            }
            //有数据刷新
            if (weakSelf.sumArr.count > 0) {
                //在主线程刷新页面
                dispatch_async(dispatch_get_main_queue(), ^{
                    [weakSelf initTableView];
                });
            }
        });



    https://www.jianshu.com/p/4e997f5deda9

    3.afnetworking

    为每一个NSURLSessionDownloadTask创建AFURLSessionManagerTaskDelegate,把请求的completionHandler也放在delegate。

    从统一的回调didCompleteWithError到delegate的didCompleteWithError,再调用completionHandler返回。

    - (void)addDelegateForDownloadTask:(NSURLSessionDownloadTask *)downloadTask
                              progress:(void (^)(NSProgress *downloadProgress)) downloadProgressBlock
                           destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
                     completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
    {
        AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init];
        delegate.manager = self;
        delegate.completionHandler = completionHandler;
    
        if (destination) {
            delegate.downloadTaskDidFinishDownloading = ^NSURL * (NSURLSession * __unused session, NSURLSessionDownloadTask *task, NSURL *location) {
                return destination(location, task.response);
            };
        }
    
        downloadTask.taskDescription = self.taskDescriptionForSessionTasks;
    
        [self setDelegate:delegate forTask:downloadTask];
    
        delegate.downloadProgressBlock = downloadProgressBlock;
    }

    response

    - (void)URLSession:(NSURLSession *)session
                  task:(NSURLSessionTask *)task
    didCompleteWithError:(NSError *)error
    {
        AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];
    
        // delegate may be nil when completing a task in the background
        if (delegate) {
            [delegate URLSession:session task:task didCompleteWithError:error];
    ...
    //需要加锁
    - (AFURLSessionManagerTaskDelegate *)delegateForTask:(NSURLSessionTask *)task {
        NSParameterAssert(task);
    
        AFURLSessionManagerTaskDelegate *delegate = nil;
        [self.lock lock];
        delegate = self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)];
        [self.lock unlock];
    
        return delegate;
    }
    
    ...
    //每一个delegate
    
    #pragma mark - NSURLSessionTaskDelegate
    
    - (void)URLSession:(__unused NSURLSession *)session
                  task:(NSURLSessionTask *)task
    didCompleteWithError:(NSError *)error
    {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wgnu"
        __strong AFURLSessionManager *manager = self.manager;
    
        __block id responseObject = nil;
    
        __block NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
        userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer;
    
        //Performance Improvement from #2672
        NSData *data = nil;
        if (self.mutableData) {
            data = [self.mutableData copy];
            //We no longer need the reference, so nil it out to gain back some memory.
            self.mutableData = nil;
        }
    
        if (self.downloadFileURL) {
            userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL;
        } else if (data) {
            userInfo[AFNetworkingTaskDidCompleteResponseDataKey] = data;
        }
    
        if (error) {
            userInfo[AFNetworkingTaskDidCompleteErrorKey] = error;
    
            dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
                if (self.completionHandler) {
                    self.completionHandler(task.response, responseObject, error);
                }
    
                dispatch_async(dispatch_get_main_queue(), ^{
                    [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
                });
            });
        } else {
            dispatch_async(url_session_manager_processing_queue(), ^{
                NSError *serializationError = nil;
                responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError];
    
                if (self.downloadFileURL) {
                    responseObject = self.downloadFileURL;
                }
    
                if (responseObject) {
                    userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject;
                }
    
                if (serializationError) {
                    userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError;
                }
    
                dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
                    if (self.completionHandler) {
                        self.completionHandler(task.response, responseObject, serializationError);
                    }
    
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
                    });
                });
            });
        }
    #pragma clang diagnostic pop
    }
  • 相关阅读:
    串匹配模式中的BF算法和KMP算法
    “隐藏与显示”的多种方法实现
    原生js实现tooltip提示框的效果
    心向旋转巧得木马 峰回路转偶得时钟
    jQuery 之 验证表单
    Java代码添加背景音乐
    svg动画 之 我的自制太阳系
    java_22 Map接口
    java_22.1 Map 的应用
    java_18 Collection接口
  • 原文地址:https://www.cnblogs.com/javastart/p/9855825.html
Copyright © 2011-2022 走看看