2011-12-19 5 views
0

私はNSOperationを使用してダウンロードする必要があるデータを収集します(2〜5秒かかる)し、その後ダウンロードします。以前に収集したデータのダウンロードを開始するには、このNSOperation内にASINetworkQueueを配置しました。ASINetworkQueue NSOperationブロッキングメインスレッド内

すべて正常に動作しますが、ASINetworkQueuecancelAllOperationsと電話すると、メインスレッドがブロックされ、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

+0

珍しいかもしれませんが、間違っていますか?私はそれが私の問題に対する最もクリーンな解決策だと思う。リクエストをロードしてからダウンロードしてください。私がこれをやっているのは、たくさんのリクエストを作成しなければならないし、ダウンロードするファイル名をロードするのに3〜4秒かかるからです。 – MoFuRo

+0

個人的に私は1つのキューを使い、 'NSOperation'は、別のキューを作成するのではなく、同じキューに操作を追加します。 ASINetworkQueueを設定するために使用するコードを表示できますか? – paulbailey

答えて

0

ASI要求応答とキュー応答は、ライブラリ設計の目的で意図的にメインスレッドに移動されます。 2つの解決方法があります。 - サブクラスASIHTTPRequestと2つのメソッドを上書きします。 (コード内で "メインスレッドのサブクラス"のようなものを探してください)。 - ライブラリを変更します。 (簡単ですが、個人的に私はこの解決策が嫌いです)。

0

何をしますか? ASIHTTPRequestはデフォルトでメインスレッド上でそれを実行します。したがって、処理が多い(または要求が多い)場合、かなりの時間がかかる可能性があります。

+0

BOOL変数のみを設定しています。私はこの部分を削除したので、これは問題にはなりません。私はNSOperationなしで同じものをテストしましたが、同じ問題が発生しています。すべてのリクエストがキャンセルされるまで、UIはフリーズします。私はキャンセルされなければならない120件のリクエストについて話していますが、それは問題ではありませんか、間違っていますか? – MoFuRo

+0

計測器プロファイラツールを実行して、遅延が発生したときにメインスレッドで実際に何が起きているのかを把握してください。可能であれば、リクエストをキャンセルする前に、各リクエストのキューとデリゲートの設定を解除することもできます。興味深い! – JosephH

2

私は同じ問題を抱えていたし、呼び出すことによって解決:呼び出す前に

[queue setShouldCancelAllRequestsOnFailure:NO] 

を:

[queue cancelAllOperations]. 
+0

!私はこれを試してみる。 – MoFuRo

関連する問題