我正在使用AFNetworking库,这是非常好的,但是我无法跟踪NSOperationQueue中的操作。我正在将NSOperation对象添加到NSOperationQueue中,我需要跟踪进度 - 所以更新UIProgressView以显示队列完成的距离,然后在队列完成后执行一段代码。
我已经尝试过KVO - 使用这里的答案:Get notification when NSOperationQueue finishes all tasks但是我遇到了问题(详细说明了那里的第二个答案),有时队列中的操作可能足够快地完成以暂时减少operationCount属性为0 - 然后导致接受的答案中的代码出现问题 - 即在队列中的所有对象完成后过早执行要执行的代码,因此进度跟踪将不准确。
我尝试过的一个变体是检查每个NSOperation的成功块中的operationCount == 0,我将其添加到NSOperationQueue然后根据它执行代码,例如
[AFImageRequestOperation *imgRequest = [AFImageRequestOperation imageRequestOperationWithRequest:urlRequest success:^(UIImage *image) {
//Process image & save
if(operationQ.operationCount == 0){
// execute completion of Queue code here
}
else {
// track progress of the queue here and update UIProgressView
}
}];
但是,我提出了与KVO相同的问题。
我已经考虑过使用GCD和一个使用完成块的调度队列 - 所以异步调度一个NSOperationQueue然后执行完成块但是这并没有解决我在跟踪队列方面的问题更新UIProgressView的进度。
也没用过
AFHttpClient enqueueBatchOfHTTPRequestOperations:(NSArray *) progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations)progressBlock completionBlock:^(NSArray *operations)completionBlock
因为我的图片来自几个不同的网址(而不是一个基本网址)。
任何建议或指示将不胜感激。感谢。
最后更新:
最后在Matt的帮助下使用AFHTTPClient enqueueBatchOfHTTPRequestOperations解决了这个问题(参见接受的答案)并注意评论。
我确实遇到过另一种不使用AFHTTPClient的解决方案,而是单独使用NSOperationQueue。我已将其包括在内,以防任何人使用它,但如果您使用AFNetworking图书馆,我建议您接受的答案(因为它最常见)优雅且易于实施)。
答案 0 :(得分:4)
AFHTTPClient -enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock:是执行此操作的正确方法。该方法采用一系列请求操作,可以从任意请求构建 - 而不仅仅是共享域。
答案 1 :(得分:2)
另一个(不那么优雅)的解决方案,如果你只使用NSOperationQueue而不是AFHTTPClient,则如下(假设以下代码将在某个循环中创建多个请求并添加到NSOperationQueue)。
[AFImageRequestOperation *imgRequest = [AFImageRequestOperation imageRequestOperationWithRequest:urlRequest success:^(UIImage *image) {
//Process image & save
operationNum++
//initially operationNum set to zero, so this will now increment to 1 on first run of the loop
if(operationNum == totalNumOperations){
//totalNumOperations would be set to the total number of operations you intend to add to the queue (pre-determined e.g. by [array count] property which would also be how many times the loop will run)
// code to execute when queue is finished here
}
else {
// track progress of the queue here and update UIProgressView
float progress = (float)operationNum / totalNumOperations
[progView setProgress:progress] //set the UIProgressView.progress property
}
}];
将这些NSOperation对象添加到NSOperationQueue将确保在执行嵌入每个NSOperation对象的成功块中的队列完成代码之前,每个操作的成功块都将完成。注意NSOperationQueue.operationCount属性未被使用,因为它在快速操作时不可靠,因为在退出队列的操作之间和在添加下一个操作之前可能存在状态,其中operationCount为零,因此我们比较了NSOperationQueue。 operationCount = 0,然后队列的完成代码将过早执行。