2012-08-11 25 views
4

我使用ASIHTTPRequest和NSOperationQueue從不同鏈接下載數據到如何知道nsoperation隊列何時完成所有請求,以便我可以重新加載我的tableview?

在後臺線程中下載。當請求結束時,我解析使用requestFinished

ASIHTTPRequest的委託方法。我想更新tableview中的數據,當

中的所有請求都已經完成。有什麼辦法可以知道NSOperationQueue何時處理了所有的

請求?我的意思是隊列有像'isEmpty'或像'queueDidCompletedAllOperation'的任何委託方法的變量?

請大家幫忙。

下面是代碼:

//source 

@interface SourceModel : NSObject 

@property (nonatomic, retain) NSString * link; 

@property (nonatomic, retain) NSString * name; 

@end 


//for rssGroup 

@interface CompleteRSSDataModel : NSObject 

@property (nonatomic,strong) SourceModel * source; 

@property (nonatomic,strong) KissXMLParser * parser; 

@property (nonatomic,strong) NSArray * rssArticles; 

@end 

- (void)viewDidLoad 
{ 
     for (int index=0; index<[rssGroups count]; index++) { 

      NSString * urlString = [[[rssGroups objectAtIndex:index] source] link]; 

      NSURL *url = [NSURL URLWithString:urlString]; 

      ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; [request setDelegate:self]; 

      //set this request's tag to group index of this source(link). See requestFinished for use of this :) 
      [request setTag:index]; 

      [self.queue addOperation:request]; 
     } 

} 


- (void)requestFinished:(ASIHTTPRequest *)request { 

    NSLog(@"%@",@"RSS Data got from internet successfully :))"); 


    int groupIndex = [request tag]; 

    CompleteRSSDataModel * group = [rssGroups objectAtIndex:groupIndex]; 

    group.parser = [[KissXMLParser alloc]initWithData:[request responseData]]; 

    if (group.parser == nil) { 

     NSLog(@"%@",@"Failed - Error in parsing data :(("); 
    } 

    else { 
     NSLog(@"%@",@"Data Parsed successfully :))"); 

     group.rssArticles = [group.parser itemsInRss]; 

     //So i want to check here that queue is empty, reload data, but as my information, i don't know any method like hasCompletedAllRequested 

     //if(self.queue hasCompletedAllRequests) { 

     //  [self.tableview reloadData]; 
     //} 


    } 
} 

- (void)requestFailed:(ASIHTTPRequest *)request { 

    NSLog(@"%@",@"Error in Getting RSS Data from internet:(("); 

} 
+0

你可能會想分享你已經在這裏嘗試 - 即所遇到的研究,問題等的代碼牆並沒有真正的人想誰做任何事幫助。 – nil 2012-08-11 04:57:55

+0

可能你是對的。我需要編輯這個問題。感謝您的建議 – iMemon 2012-08-11 05:12:06

回答

10

如果所有操作都已完成,則operations陣列數將爲零。

要檢查這一點,你可以使用Key值觀察編碼觀察員的NSOperationQueue

operations鍵設置爲重點opertions觀察者會像下面:

[self.queue addObserver:self forKeyPath:@"operations" options:0 context:NULL]; 

然後在做到這一點你observeValueForKeyPath如下:

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
         change:(NSDictionary *)change context:(void *)context 
{ 
    if (object == self.queue && [keyPath isEqualToString:@"operations"]) { 
     if ([self.queue.operations count] == 0) { 
      // Do something here when all operations has completed 
      NSLog(@"queue has completed"); 
     } 
    } 
    else { 
     [super observeValueForKeyPath:keyPath ofObject:object 
           change:change context:context]; 
    } 
} 

在iOS 4.0之後,您可以使用屬性operationCountself.queue.operationCount == 0而不是檢查這樣[self.queue.operations count] == 0

+0

謝謝。這解決了我的問題:) – iMemon 2012-08-11 05:39:55

0

幾個選項我撲過來:

  1. 使用ASINetworkQueue代替,並設置queueDidFinishSelector,所以它會告訴你,當它完成。這也使您不僅可以更新UIProgressView視圖,而且還可以爲整個下載過程更新另一個視圖。

  2. 你可以添加一些東西到你的NSOperationQueue只需調用一個方法然後更新你的用戶界面(當然在主隊列中)?通過將其添加到隊列中,直到它清除隊列後纔會進入隊列。或者在另一個隊列中,調用waitUntilFinished,此時您可以更新您的UI。

  3. 看着你的評論,它看起來像你在requestFinished更新你的用戶界面,但不滿意,因爲你認爲等待所有的更新可能會更好。就我個人而言,我更喜歡通過請求更新UI和請求,如果速度緩慢,您會獲得臨時反饋,而不是等待所有內容。這一定要優雅地完成,但我喜歡隨着更新UI。無可否認,有些流程並不適用於此。

在這最後一點,我想訣竅是做這些更新,所以它不會分散注意力。具體來說,如果你的用戶界面是UITableView,你可能做而不是想要做tableView.reloadData,這將重新加載整個表。相反,你可能要檢查,看看如果電池仍然加載(通過cellForRowAtIndexPath,該UITableView方法,不要與UITableViewController方法tableView:cellForRowAtIndexPath混淆),如果是,更新是一排,例如:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section]; 
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; 
if (cell) 
{ 
    // you can either update the controls in the cell directly, or alternatively, just 
    // call reloadRowsAtIndexPaths to have the tableView use your data source: 

    [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
          withRowAnimation:UITableViewRowAnimationFade]; 
} 
+0

您是對的。目前我正在更新ui中的requestFinished,但我覺得這不是正確的方法。我認爲ASINetworkQueue可能是一個不錯的選擇。我會去嘗試一下。但是我想問一下它是否會像NSOperationQueue一樣在後臺下載? – iMemon 2012-08-11 05:34:24

+0

是的,它在我的代碼中。此外,它還提供了一些其他優點(例如,如果您使用UIProgressView,則可以爲整個排隊作業創建一個)。 – Rob 2012-08-11 05:36:27

+0

目前我正在更新ui requestFinished,因爲你說過。但問題是,當我有多個請求時,我需要在所有請求完成後更新ui。然後我用[self.queue.operation count]消息解決它。當它變成零時,我可以安全地更新ui。現在我可以使用這種方法顯示下載進度。無論如何,謝謝:) – iMemon 2012-08-13 07:34:16

2

我知道這已經回答了,但對於未來的讀者,如果你正在使用AFNetworking,更具體地說,AFHTTPRequestOperation你可以做這樣的事情:

NSString *urlPath = [NSString stringWithFormat:@"%@%@", baseUrl, file]; 
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlPath]]; 

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 

[operation setCompletionBlockWithSuccess: 
^(AFHTTPRequestOperation *operation, id responseObject) { 
    if ([[queue operations] count] ==0) { 
     NSNotification * success = [NSNotification notificationWithName:@"TotalDone" object:[NSNumber numberWithBool: YES]]; 
     [[NSNotificationCenter defaultCenter] postNotification:success]; 
     queueSize = 0; 
    } else { 

     //get total queue size by the first success and add 1 back 
     if (queueSize ==0) { 
      queueSize = [[queue operations] count] +1.0; 
     } 
     float progress = (float)(queueSize-[[queue operations] count])/queueSize; 
     NSNumber * totProgress = [NSNumber numberWithFloat:progress]; 
     NSNotification * totalProgressNotification = [NSNotification notificationWithName:@"TotalProgress" 
                          object:totProgress]; 
     [[NSNotificationCenter defaultCenter] postNotification:totalProgressNotification]; 
    } 


} failure:^(AFHTTPRequestOperation *operation, NSError *error) 
     NSLog(@"Error: %@", error); 
     }]; 

這是爲下載器添加一個下載到NSOperationQueue,然後通知兩個進度條:1爲文件進度,1爲總進度。

希望這有助於

相關問題