NSURLConnectionの委任とスレッド化-iPhone
-
06-07-2019 - |
質問
NSURLConnectionを介してアプリドキュメントディレクトリ内の2つの.plistファイルを更新するクラスがあります。クラスは、NSURLConnectionの独自のデリゲートとして機能します。 1つのファイルを要求すると正常に機能しますが、2つのファイルを更新しようとすると失敗します。 getNewDatabaseメッセージごとに新しいスレッドを開始するように見えますか?
- (void)getAllNewDatabases {
[self performSelectorOnMainThread:@selector(getNewDatabase:) withObject:@"file1" waitUntilDone:YES];
[self performSelectorOnMainThread:@selector(getNewDatabase:) withObject:@"file2" waitUntilDone:YES];
}
- (BOOL)getNewDatabase:(NSString *)dbName
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableString *apiString = [[NSMutableString alloc] initWithString:kAPIHost];
[apiString appendFormat:@"/%@.plist",dbName];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:apiString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSURLConnection *myConnection = [[NSURLConnection alloc] initWithRequest:myRequest delegate:self];
[apiString release];
if( myConnection )
{
//omitted for clarity here
}
[pool release];
}
//NSURLConnection delegate methods here ...
解決
NSURLConnectionとNSThreadで何か面白いものを見つけました-スレッドは、呼び出したメソッドを実行するのに必要な間だけ存続します。
上記の場合、スレッドは getNewDatabase:(NSString *)dbName
が完了するまで有効であるため、実際に何もする前にデリゲートメソッドを強制終了します。
このウェブサイトは、問題のより良い説明と解決策を提供しています p>
少し調整して、特定の時間内に完了しなかった場合にカスタムタイムアウトができるようにしました(誰かがアクセスポイント間を歩いているときに便利です)
start = [NSDate dateWithTimeIntervalSinceNow:3];
while(!isFinished && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]]){
if([start compare:[NSDate date]] == NSOrderedAscending){
isFinished = YES;
}
}
他のヒント
現在、指定したコード内にあるため、 getNewDatabase:
はアプリケーションのメインスレッドで実行されています。この特定のケースの問題は、ジェームズが彼のケースで観察したように、スレッドのライフサイクル以外の何かです。
この操作をバックグラウンドで実行するつもりだった場合、現在のコードの問題を解決するのではなく、 NSOperationQueue
と NSOperation
の使用を検討することをお勧めします。特に、実行するダウンロードタスクが複数あることを考えると、あなたのケースは NSOperationQueue
にぴったりだと思います。
Dave Dribinには優れた記事があります NSOperation
内でのNSURLConnectionなどの非同期APIの使用について。または、バックグラウンドスレッドで実行している限り、プロセスを簡略化し、NSOperationで代わりに initWithContentsOfURL:
などの同期APIメソッドを使用することもできます。
Marcus Zarraは、チュートリアルを作成しました簡単なバックグラウンド操作のためにNSOperationQueueを組み込み、使用することがいかに簡単かを示しています。