2013-05-22 17 views
0

我使用的是AFNetworking庫,這非常棒,但是我無法跟蹤NSOperationQueue中的操作。我將NSOperation對象添加到NSOperationQueue中,我需要跟蹤進度 - 因此,更新UIProgressView以顯示隊列完成的程度,然後在隊列完成後再執行一段代碼。AFNetworking&處理NSOperationQueue - 在完成時執行代碼並跟蹤進度

我試過KVO - 在這裏使用的答案:Get notification when NSOperationQueue finishes all tasks然而我遇到了問題(詳細闡述了第二個答案)有時在隊列中的操作可能會完成足夠快,以暫時遞減operationCount屬性爲0 - 然後在接受的答案中導致代碼出現問題 - 即在隊列中的所有對象都完成並且進度跟蹤結果不準確之前提前執行代碼以執行代碼。

我試過的一個變體是在NSOperationQueue添加到每個NSOperation的成功塊中檢查operationCount == 0,然後根據它執行代碼。

[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。

,因爲我的圖片是從幾個不同的URL(而不是一個基礎URL)來還沒有使用

AFHttpClient enqueueBatchOfHTTPRequestOperations:(NSArray *) progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations)progressBlock completionBlock:^(NSArray *operations)completionBlock

任何建議或指針將不勝感激。謝謝。

只是最後更新:

在馬特的幫助下最終使用AFHTTPClient enqueueBatchOfHTTPRequestOperations(見接受的答案),並注意評論以及解決這一問題。

我確實遇到了另一個不使用AFHTTPClient的解決方案,而是僅使用NSOperationQueue。我也包括這個以防萬一它對任何人都有用,但如果你使用的是AFNetworking Library,我會推薦接受的答案(因爲它是最優雅和易於實現的)。

+0

您是否看到鏈接問題的第二個答案?這是解決問題的一種可能的方法。 –

+0

我確實看過Cory,我試着使用依賴關係,但它仍然沒有給我一個解決方案,除非我的應用程序的這種方法是不正確的。 – SMSidat

回答

4

AFHTTPClient -enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock:是這樣做的正確方法。該方法接受一系列請求操作,可以從任意請求中構建 - 而不僅僅是共享一個域。

+0

請問是否共享的基礎URL AFHTTPClient?當初始化AFHTTPClient時,或者可以調用init方法而不分配它,即[[AFHTTPClient alloc] init],什麼是合適的基礎URL? – SMSidat

+0

我只是試了一下,並附加了一個任意的基本網址(例如http://www.google.com) - 並且它似乎與上面的代碼一樣表現出相同的行爲。我認爲發生的事情是,一旦項目全部從隊列中釋放,但甚至在每個隊列項目的成功塊已經完成執行之前執行完成塊 - 是否有辦法延遲AFHTTPClient中的完成塊的執行,直到所有代碼都在包括每個成功塊的操作是否完成? – SMSidat

+2

完成塊的執行時間不能保證。我的建議是不要在批處理操作中使用completionBlocks,並且在批處理完成塊中完成所有必要的工作。 – mattt

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相反,隊列的完成代碼會過早執行。