Asynchroniczne żądanie do serwera z wątku w tle
Mam problem, gdy próbowałem wykonać asynchroniczne żądania do serwera z wątku w tle. Nigdy nie otrzymałem wyników tych próśb. Prosty przykład pokazujący problem:
@protocol AsyncImgRequestDelegate
-(void) imageDownloadDidFinish:(UIImage*) img;
@end
@interface AsyncImgRequest : NSObject
{
NSMutableData* receivedData;
id<AsyncImgRequestDelegate> delegate;
}
@property (nonatomic,retain) id<AsyncImgRequestDelegate> delegate;
-(void) downloadImage:(NSString*) url ;
@end
@implementation AsyncImgRequest
-(void) downloadImage:(NSString*) url
{
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:20.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
receivedData=[[NSMutableData data] retain];
} else {
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[delegate imageDownloadDidFinish:[UIImage imageWithData:receivedData]];
[connection release];
[receivedData release];
}
@end
Następnie nazywam to z głównego wątku
asyncImgRequest = [[AsyncImgRequest alloc] init];
asyncImgRequest.delegate = self;
[self performSelectorInBackground:@selector(downloadImage) withObject:nil];
Metoda downloadImage jest wymieniona poniżej:
-(void) downloadImage
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
[asyncImgRequest downloadImage:@"http://photography.nationalgeographic.com/staticfiles/NGS/Shared/StaticFiles/Photography/Images/POD/l/leopard-namibia-sw.jpg"];
[pool release];
}
Problem polega na tym, że metoda imageDownloadDidFinish nigdy nie jest wywoływana. Ponadto żadna z metod
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response
są nazywane. Jednak jeśli wymienię
[self performSelectorInBackground:@selector(downloadImage) withObject:nil];
przez
[self performSelector:@selector(downloadImage) withObject:nil];
wszystko działa poprawnie. Zakładam, że wątek tła umiera przed zakończeniem żądania asynchronicznego, a to powoduje problem, ale nie jestem pewien. Czy mam rację z tymi założeniami? Czy jest jakiś sposób na uniknięcie tego problemu?
Wiem, że mogę użyć żądania synchronizacji, aby uniknąć tego problemu, ale to tylko prosty przykład, rzeczywista sytuacja jest bardziej złożona.
Z góry dziękuję.