NSURLConnectionを処理するDownloadオブジェクトがあります。
次に、 Downloadオブジェクトをプロパティとして保持するNSOperationオブジェクト ( DownloadOperation ) があります。
ダウンロードオブジェクトには、開始/一時停止/再開/キャンセルの機能があります。
これはDownloadOperationのメイン メソッドです。
- (void)main
{
@autoreleasepool {
BOOL isDone = NO;
if (![self isCancelled]) {
[_download start]; //Download object start (creates NSURLConnection internally)
}
NSDate *distantFuture = [NSDate distantFuture];
while(!isDone && ![self isCancelled]) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:distantFuture];
if (!_download.isActive) { //internal state of Download
isDone = YES;
}
}
[self completeOperation]; //this sets finished and executing flags
}
}
外部から (UI から)、Downloadオブジェクトを操作します: Start、Pause、Resume、Cancel。そして、内部的に状態を変更しているため、ダウンロードが終了またはキャンセルされると、isActiveがNOに設定され、while ループが終了するはずです。
これは、ダウンロードを開始して終了させると機能します (バックグラウンドで、NSURLConnectionが終了し、デリゲートと呼ばれます - connectionDidFinish ...)
Downloadを一時停止/再開 すると、ダウンロードはダウンロードを続行して終了します (そして、その内部状態を変更します: isActive -> NO )。一時停止するとNSURLConnectionをキャンセルし、再開すると新規作成します。
または、ダウンロードをキャンセルすると、非アクティブになります ( NSURLConnectionがキャンセルされます)。
しかし、ここに問題があります:
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:distantFuture];
これらの場合 ( NSURLConnectionをキャンセルした場合) は決して返されず、「if」ステートメントは処理されないため、このDownloadOperationは常に実行中と見なされ、決してNSOperationQueueを終了しません。
その実行ループを起動させる可能性のあるイベントが発生しないようです。
私は試した
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.05]];
この種の機能はうまくいきますが、それほどスムーズではなく、最善の解決策ではないと思います。
私が本当に知りたいのは、そのNSRunLoopを強制的にウェイクアップさせる方法 (ウェイクアップさせるイベントを発生させる方法) と while ループを続行する方法です。