2011-12-19 53 views
0

我使用NSOperation來收集應該下載的數據(需要2-5秒),然後我下載它。我在這個NSOperation裏放了一個ASINetworkQueue,開始下載之前收集的數據。NSINperation內的ASINetworkQueue阻止主線程

一切正常,但當我在我的ASINetworkQueue上調用cancelAllOperations時,主線程塊和UI凍結。這是爲什麼發生?其他一切正常。

這裏是我的代碼:

- (void)main { 
    //ManagedObjectContext for operations 
    AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate]; 
    self.managedObjectContext = [[NSManagedObjectContext alloc] init]; 


    [self.managedObjectContext setPersistentStoreCoordinator: [appDelegate persistentStoreCoordinator]]; 

    // Register context with the notification center 
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
    [nc addObserver:self 
      selector:@selector(mergeChanges:) 
       name:NSManagedObjectContextDidSaveNotification 
      object:self.managedObjectContext]; 


    [self startDownload]; 


    if (!self.downloadDidFail) { 
     [self moveFiles]; 

     [self.managedObjectContext save:nil]; 
    } 
} 

- (void)startDownload {  
    self.downloadQueue = [ASINetworkQueue queue]; 
    self.downloadQueue.delegate = self; 
    [self.downloadQueue setRequestDidFailSelector:@selector(dataRequestFailed:)]; 
    [self.downloadQueue setRequestDidFinishSelector:@selector(dataRequestFinished:)]; 
    [self.downloadQueue setQueueDidFinishSelector:@selector(dataQueueFinished:)]; 
    [self.downloadQueue setShouldCancelAllRequestsOnFailure:YES]; 
    [self.downloadQueue setDownloadProgressDelegate:self.progressView]; 

    for (File *dataFile in self.dataFiles) { 
      ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:dataFile.url]]; 
      [request setDownloadDestinationPath:dataFile.path]; 

      [self.downloadQueue addOperation:request]; 
     } 
    } 

    [self.downloadQueue go]; 
    [self.downloadQueue waitUntilAllOperationsAreFinished]; 
} 

- (void)dataRequestFinished:(ASIHTTPRequest *)request { 
    NSLog(@"DL finished"); 
} 

- (void)dataRequestFailed:(ASIHTTPRequest *)request { 
    DLog(@"Download failed"); 

    self.downloadDidFail = YES; 
} 

- (void)dataQueueFinished:(ASINetworkQueue *)queue { 
    DLog(@"Finished Data Queue"); 
} 

- (void)cancelDownload { 
    self.canceledDownload = YES; 

    [self.downloadQueue cancelAllOperations]; 
} 
+0

似乎一個不尋常的方式把一個'ASINetworkQueue'(NSOperationQueue'的'子類)內一個'NSOperation'。 – paulbailey 2011-12-19 11:35:15

+0

不尋常,也許,但它是錯的?我認爲這是對我的問題最乾淨的解決方案。加載請求並在之後下載。我這樣做的原因是因爲有很多請求必須被創建,並且加載應該被下載的文件名需要大約3-4秒 – MoFuRo 2011-12-19 16:38:14

+0

個人而言,我會使用一個隊列,然後有最初的「NSOperation」將操作添加到同一個隊列中,而不是創建另一個隊列。你能告訴我們你用來設置你的'ASINetworkQueue'的代碼嗎? – paulbailey 2011-12-19 17:00:27

回答

0

ASI請求響應並且隊列響應被有意地移動到主線程用於庫設計目的。 您有兩種解決方案: - 子類ASIHTTPRequest並覆蓋2種方法。 (在代碼中查找類似「主線程的子類」)。 - 修改庫。 (容易,但我個人不喜歡這個解決方案)。

0

什麼是你的失敗委託方法呢? ASIHTTPRequest默認會在主線程上運行,所以如果它執行了很多處理(或者有很多請求),這可能需要一段時間。

+0

它只設置一個BOOL變量。這不是問題,因爲我已經刪除了這部分。我只是在沒有NSOperation的情況下測試過相同的問題。用戶界面凍結,直到所有請求都被取消。我在談論120個需要取消的請求,但這不應該是問題,還是我錯了? – MoFuRo 2011-12-19 16:33:41

+0

嘗試運行在儀器分析器工具中,找出延遲發生時主線程上實際發生的情況。可能您也可以在取消請求之前嘗試取消設置隊列的委託和每個請求。 – JosephH 2011-12-19 18:45:32

2

我有同樣的問題,並通過調用解決:

[queue setShouldCancelAllRequestsOnFailure:NO] 

之前調用:

[queue cancelAllOperations]. 
+0

有趣!我會試試這個。 – MoFuRo 2012-02-17 09:23:13