更新:executing 和finishing 属性保存有关当前NSOperation 状态的信息。一旦您将finishing 设置为YES 并将executing 设置为NO,您的操作将被视为已完成。正确的处理方式不需要dispatch_group,可以简单的写成异步的NSOperation:
- (BOOL) isAsynchronous {
return YES;
}
- (void) main
{
// We are starting everything
self.executing = YES;
self.finished = NO;
NSURLSession * session = [NSURLSession sharedInstance];
NSURL *url = [NSURL URLWithString:@"http://someurl"];
NSURLSessionDataTask * dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
/* Do your stuff here */
NSLog("Will show in second");
self.executing = NO;
self.finished = YES;
}];
[dataTask resume]
}
asynchronous 一词具有很大的误导性,并不是指 UI(主)线程和后台线程之间的区别。
如果isAsynchronous设置为YES,表示部分代码是异步执行的main方法。换一种说法:在main方法内部进行了异步调用,该方法将在main方法完成后完成。
我有一些关于如何在苹果操作系统上处理并发的幻灯片:https://speakerdeck.com/yageek/concurrency-on-darwin。
旧答案:你可以试试dispatch_group_t。您可以将它们视为 GCD 的保留计数器。
想象一下NSOperation 子类的main 方法中的以下代码:
- (void) main
{
self.executing = YES;
self.finished = NO;
// Create a group -> value = 0
dispatch_group_t group = dispatch_group_create();
NSURLSession * session = [NSURLSession sharedInstance];
NSURL *url = [NSURL URLWithString:@"http://someurl"];
// Enter the group manually -> Value = Value + 1
dispatch_group_enter(group); ¨
NSURLSessionDataTask * dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
/* Do your stuff here */
NSLog("Will show in first");
//Leave the group manually -> Value = Value - 1
dispatch_group_leave(group);
}];
[dataTask resume];
// Wait for the group's value to equals 0
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog("Will show in second");
self.executing = NO;
self.finished = YES;
}