在 For 循环后添加带有依赖项的 NSOperation

问题描述 投票:0回答:2

所以我试图在所有块操作之后执行

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 请求。

ios multithreading facebook nsoperation
2个回答
2
投票

我猜测

performRequestWithHandler:
会立即返回,因为它采用回调块作为其参数。一旦 NSBlockOperation 的块返回,该操作就被认为已完成,因此所有操作都会立即完成,只有稍后才会调用它们的完成块。

您可能需要子类化 NSOperation 并实现并发方法(最少:

start
isConcurrent
isExecuting
isFinished
)而不是非并发方法(最少:
main
)。来自
performRequestWithHandler:
的回调应该触发状态相关属性的键值通知,以指示 NSOperation 已完成。


0
投票

NSOperations 一旦被添加到 NSOperationQueue 中,就会调用它们的 -start 方法。因此,当您调用 [queue addOperation:operation]; 时,for 循环内的每个操作都会启动。

由于lastOperation将操作设置为依赖项,因此每次这些操作完成时都会调用它,这可能发生在将lastOperation添加到队列之前。

© www.soinside.com 2019 - 2024. All rights reserved.