所以我试图在所有块操作之后执行
lastOperation
,但由于某种原因它首先被执行。这是为什么呢?添加依赖项是错误的方法吗?
[self facebookAccount:^(NSError *error, ACAccount *facebookAccount) {
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];
NSBlockOperation *lastOperation = [NSBlockOperation blockOperationWithBlock:completionAll];
for (NSString *postID in postIDs) {
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSString *postIDString = [NSString stringWithFormat:@"https://graph.facebook.com/v2.0/%@", postID];
NSURL *postIDURL = [NSURL URLWithString:postIDString];
SLRequest *postIDRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:postIDURL parameters:nil];
postIDRequest.account = facebookAccount;
[postIDRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSError *parseError;
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:&parseError];
completion(response);
}];
}];
[queue addOperation:operation];
[lastOperation addDependency:operation];
}
[queue addOperation:lastOperation];
}];
如果我在 [self facebookAccount:^(NSError *error, ACAccount *facebookAccount)] 中添加以下代码:
[RACObserve(queue, operationCount) subscribeNext:^(id x) {
NSLog(@"Operation count for queue: %@", x);
}];
那么控制台的输出是:
https://i.sstatic.net/w5akr.png(抱歉我不能发图片,但我很快就会提高我的声誉)
“全部完成”的位置通常在 5 到 10 之间变化。所以我很确定这取决于队列到达最后一个操作之前哪个 NSOperations 完成处理 GET 请求。
我猜测
performRequestWithHandler:
会立即返回,因为它采用回调块作为其参数。一旦 NSBlockOperation 的块返回,该操作就被认为已完成,因此所有操作都会立即完成,只有稍后才会调用它们的完成块。
您可能需要子类化 NSOperation 并实现并发方法(最少:
start
、isConcurrent
、isExecuting
和 isFinished
)而不是非并发方法(最少:main
)。来自 performRequestWithHandler:
的回调应该触发状态相关属性的键值通知,以指示 NSOperation 已完成。
NSOperations 一旦被添加到 NSOperationQueue 中,就会调用它们的 -start 方法。因此,当您调用 [queue addOperation:operation]; 时,for 循环内的每个操作都会启动。
由于lastOperation将操作设置为依赖项,因此每次这些操作完成时都会调用它,这可能发生在将lastOperation添加到队列之前。