Ios 在For循环后添加具有依赖项的NSO操作

Ios 在For循环后添加具有依赖项的NSO操作,ios,facebook,multithreading,graph,nsoperation,Ios,Facebook,Multithreading,Graph,Nsoperation,所以我试图在所有的块操作之后执行lastOperation,但出于某种原因,它是先执行的。为什么会这样?添加依赖项是错误的做法吗 [self facebookAccount:^(NSError *error, ACAccount *facebookAccount) { NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue setMaxConcurrentOperationCount:1]; NS

所以我试图在所有的块操作之后执行
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)]中添加以下代码:

然后,控制台的输出为:

(很抱歉,我无法发布照片,但我很快就会提高声誉)


“全部完成”的位置通常在5到10之间变化。因此,我非常确定这取决于哪个NSOperations在队列到达最后一个操作之前完成了GET请求的处理。

NSOperations在添加到NSOperationQueue后立即调用其-start方法。因此,当您调用[queue addOperation:operation]时,for循环中的每个操作都会启动


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

我猜是
performRequestWithHandler:
会立即返回,因为它将回调块作为参数。NSBlockOperation的块一返回,该操作即被视为已完成,因此您的所有操作都会立即完成,直到稍后才会调用它们的完成块


您可能需要将NSOperation子类化并实现并发方法(最小值:
start
isConcurrent
isExecuting
isFinished
),而不是非并发方法(最小值:
main
)。来自
performRequestWithHandler:
的回调应触发与状态相关属性的键值通知,以指示NSO操作已完成。

对于明显的问题,很抱歉,但是您是否有多篇文章?在将操作添加到队列之前,您是否尝试设置依赖关系?我不能说为什么它不工作,但我会尝试重构,看看它是否工作。然后试着从中吸取教训。尝试的一件事是将所有post块添加到单个块操作中,因为它们将被执行,并且只有当所有块都完成时,操作才会被视为完成。你能更清楚地说明你希望看到什么吗?在代码中放入一些NSLog调用,如NSLog(@“1”);然后告诉我们您看到它们的顺序以及您希望看到它们的顺序。是的,很抱歉,这段代码正在添加一组NSOperations,它们发出GET请求并处理对NSOperationQueue的响应。我想知道NSOperationQueue何时不仅完成了GET请求,还完成了对它们的处理。这个问题不包括处理,但它是块“完成(响应)”,它所做的是将解析的“响应”存储在核心数据实体中。“completionAll()”块是在完成所有操作时应该调用的块。我确实尝试在操作之前添加依赖项,但没有成功。因此,我使用ReactiveCocoa进行键值观察,并观察NSOperationQueue的operationCount和NSLogging发送的所有内容。在我的completionAll()中,这是最后一个操作的块,我只需要NSLog(“全部完成”)。我编辑我的帖子是为了向您展示它的样子。因此,如果我让我的操作在执行回调中的任何操作时执行,然后相应地完成,NSOperationQueue将自动等待直到isFinished信号移动到下一个操作?将我的setMaxConcurrentOperationCount保持为1应该可以做到这一点吗?如果是这样,我认为这是一个非常有用的评论,谢谢!当然,我也可以支持这一点;我已经在我的代码库中工作过了。此外,子类化
NSOperation
并以这种方式构造代码可以为我提供干净的“工作单元”,我可以根据需要进行转换(或链接在一起)。另外,虽然我相信您可以为块操作提供
NSString
名称表示,但在调试时,子类化
NSOperation
可以为代码提供更清晰的外观,尤其是在堆栈跟踪中。谢谢,这正是我所需要的。我会在它工作后更新它,但这似乎是一个相当简单的解决方案。
[RACObserve(queue, operationCount) subscribeNext:^(id x) {
        NSLog(@"Operation count for queue: %@", x);
    }];