记录dispatch_group_enter()和dispatch_group_leave()的使用

来源:互联网 发布:mac 休眠不断网 编辑:程序博客网 时间:2024/05/17 07:58

        今天在读AFNetworking源码的时候看到很多GCD的使用,查阅相关资料了解了一些常用方法后记录了下来,加强记忆,便于以后查阅。

源码片段如下:

- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success                              failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure{    // completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle.#pragma clang diagnostic push#pragma clang diagnostic ignored "-Warc-retain-cycles"#pragma clang diagnostic ignored "-Wgnu"    self.completionBlock = ^{        if (self.completionGroup) {            dispatch_group_enter(self.completionGroup);        }        dispatch_async(http_request_operation_processing_queue(), ^{            if (self.error) {                if (failure) {                    dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{                        failure(self, self.error);                    });                }            } else {                id responseObject = self.responseObject;                if (self.error) {                    if (failure) {                        dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{                            failure(self, self.error);                        });                    }                } else {                    if (success) {                        dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{                            success(self, responseObject);                        });                    }                }            }            if (self.completionGroup) {                dispatch_group_leave(self.completionGroup);            }        });    };#pragma clang diagnostic pop}
        初次阅读这段代码的时候,对dispatch_group_enter()和dispatch_group_leave()的用法不是很了解,苹果官方的文档说明如下:

dispatch_group_enter():

<span style="font-family:Courier New;font-size:10px;">Calling this function increments the current count of outstanding tasks in the group. Using this function (with dispatch_group_leave) allows your application to properly manage the task reference count if it explicitly adds and removes tasks from the group by a means other than using the dispatch_group_async function. A call to this function must be balanced with a call to dispatch_group_leave. You can use this function to associate a block with more than one group at the same time.</span>

dispatch_group_leave():
<span style="font-family:Courier New;">Calling this function decrements the current count of outstanding tasks in the group. Using this function (with dispatch_group_enter) allows your application to properly manage the task reference count if it explicitly adds and removes tasks from the group by a means other than using the dispatch_group_async function.A call to this function must balance a call to dispatch_group_enter. It is invalid to call it more times than dispatch_group_enter, which would result in a negative count.</span>
       dispatch_group_enter()显式的指明一个任务执行块进入了这个组,dispatch_group_leave()显式表明执行块执行完毕,移除出组。对于同步任务,这两个方法结合起来的效果等同于dispatch_group_async();而当执行的任务为异步的时候,用dispatch_group_async()就会出现问题,如:

dispatch_group_async(group, queue, ^{        [self performBlock:^(){            block();        }];    });
        上述代码中,block()就无法得到执行。这个时候,需要结合dispatch_group_enter()和dispatch_group_leave()来实现:

<span style="font-size:10px;">dispatch_group_enter(group);         [self performBlock:^(){             block();             dispatch_group_leave(group); }]; </span>
        异步任务回调后才算这个group任务完成。
        另外,上述代码中出现了如下片段:
#pragma clang diagnostic push#pragma clang diagnostic ignored "-Warc-retain-cycles"#pragma clang diagnostic ignored "-Wgnu"    ...    ...#pragma clang diagnostic pop
        其作用是忽略中间代码的循环引用的警告以及一些特定的编译警告,具体内容可查阅http://clang.llvm.org/docs/UsersManual.html#diagnostics_pragmas

0 0