所以我尝试在所有块操作之后执行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);
}];
然后输出到控制台是:
http://i.imgur.com/efrouOC.png(抱歉,我无法发布图片,但我很快就会获得声誉)
“全部完成”的位置通常在5到10之间变化。所以我很确定这取决于哪个NSOperations在队列到达lastOperation之前完成了处理GET请求。
答案 0 :(得分:2)
我猜测performRequestWithHandler:
会立即返回,因为它需要一个回调块作为其参数。一旦NSBlockOperation的块返回,操作就被认为已完成,因此所有操作都会立即完成,并且只有稍后才会调用它们的完成块。
您可能需要继承NSOperation并实现并发方法(最少:start
,isConcurrent
,isExecuting
和isFinished
)而不是非并发方法(最小值:main
)。来自performRequestWithHandler:
的回调应触发与状态相关的属性的键值通知,以指示NSOperation已完成。
答案 1 :(得分:0)
NSOperations在将它们添加到NSOperationQueue后立即调用它们的-start方法。因此,当你调用[queue addOperation:operation]时,for循环中的每个操作都会被启动;
由于lastOperation将操作设置为依赖项,因此每次操作完成时都会调用它,这可能在将lastOperation添加到队列之前发生。