Instagram風のように、一度にたくさんの場所に画像をアップロードするアプリがあります。
これは、非同期の周りに多数NSOperationQueue
のラッパーを実行するでセットアップされます。NSOperation
NSURLConnection
このように始まるほとんどの質問は、「呼び出し元のスレッドが戻る前に結合されているため、コールバックが呼び出されません。これはそのような質問ではありません。期待どおりにコールバックを取得していますが、アプリを何らかの形で妨げています。ホームボタンを押したときのバックグラウンドから。サンドボックスのせいでこれを完全にブロックすることはできないといつも思っていましたが、どういうわけかそれを実行しました。操作の実行中にホームボタンを押しても、操作が完了するまで何も起こりません。どの時点(20〜30秒後)でアプリが適切に背景になります。
** NBこれは、シングルコアプロセッサデバイスでのみ発生するようです。iPhone 4でのみ再現できますが、4SまたはiPad3では再現できません。*
まだ興味がある?これが私の設定です:
self.uploadQueue = [[NSOperationQueue alloc] init];
[self.uploadQueue setMaxConcurrentOperationCount:1];
[self.uploadQueue setSuspended:YES];
後で、キューに操作を追加し、一時停止を解除して開始します。NSOperation
これらのサブクラスのコードは次のとおりです。
- (BOOL)isConcurrent { return YES; }
- (BOOL)isExecuting { return self.executing; }
- (BOOL)isFinished { return self.finished; }
- (void)start {
// Omitted: check for cancel...
// Omitted: check if setup to run
[self willChangeValueForKey:@"isExecuting"];
self.executing = YES;
[self didChangeValueForKey:@"isExecuting"];
[self.sharer share];
CFRunLoopRun();
}
- (void)completeOperation {
[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
self.executing = NO;
self.finished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
CFRunLoopStop(CFRunLoopGetCurrent());
}
このshare
メソッドは非同期をセットアップし、次のNSURLConnection
ように起動します。
- (void)share {
// Omitted: connection setup
[NSURLConnection sendAsynchronousRequest:postRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *responseData, NSError *error){
// handle error or success, then call
[self.currentOperation completeOperation];
}];
私が解決しようとしている副作用は別として、コードは想定どおりに機能し、コールバックが呼び出され、スレッドは必要な限り存続し、操作キューは指定されたものだけを実行します一度に操作の数。
私は何を試しましたか?私は試した:
- でNSURLConnectionを呼び出し
[NSOperationQueue currentQueue]
ます。これにより、非同期接続がブロックをコールバックしませんでした。 - 各NSOperationを
start
メソッドのメインスレッドに強制します。これでは問題は解決せず、コードが機能しなくなったり、UIがフリーズしたりすることもありました。 - 適切なディスパッチスレッドを取得するために、可変配列とGCDを使用して独自のキューを実装します。動作させることができませんでした。
- 操作での同期NSURLConnections。それは私にとってオプションではないので、私は実際にこれを試しませんでした。Facebook iOS SDKなどの一部のネットワークフレームワークには、同期オプションがありません。
ホームボタンを押した後、操作が完了する前に実行を一時停止しても、何も興味深いことはありません。ロックまたは実行が終了するのを待っているメインスレッドには何もないようです。
私はこれを完全なボゾのように設定していますか?ここで何が起こっているのですか、どうすれば修正できますか?