我有一个类 PictureDownloader 用于从服务器异步加载图像。它将自己指定为 NSURLConnection 的委托,因此由 NSURLConnection 保留。我在 DetailViewController 中创建了几个 PictureDownloader 来获取相应的图像,因此 DetailViewController 是每个 PictureDownloader 的委托。当用户离开 DetailViewController 时,所有剩余的下载都被取消,但有时似乎是这样的情况,即 PictureDownloader 在连接被取消之前已完成加载图像(调用了connectionDidFinishedLoading),但 DetailViewController 不再存在(但PictureDownloader 确实如此,因为它由 NSURLConnection 保留),所以调用
[self.delegate didLoadPictureWithID:self.ID];
在 PictureDownloader 内部会给出一个 EXC_BAD_ACCESS 或者有时是一个“发送到实例的无法识别的选择器”。
以下是源代码的相关部分:
在 DetailViewController 中创建 PictureDownloader
- (void)startPictureDownload:(Picture *)pic withPictureId:(NSString *)pId forID:(int)ID
{
PictureDownloader *downloader = [self.downloadsInProgress objectForKey:[NSNumber numberWithInt:ID]];
if(!downloader)
{
downloader = [[PictureDownloader alloc] init];
downloader.picture = pic;
downloader.pictureId = pId;
downloader.ID = ID;
downloader.delegate = self;
[self.downloadsInProgress setObject:downloader forKey:[NSNumber numberWithInt:ID]];
[downloader startDownload];
[downloader release];
}
}
取消下载(当 DetailViewController 返回概览时调用)
- (void)cancelAllDownloads
{
[self.downloadsInProgress enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){
[obj cancelDownload];
}];
}
当 PictureDownloader 完成加载时调用的委托方法
- (void)didLoadPictureWithID:(int)dID;
{
PictureDownloader *downloader = [self.downloadsInProgress objectForKey:[NSNumber numberWithInt:dID]];
if(downloader)
{
UIImageView *imageView = (UIImageView *)[self.view viewWithTag:dID];
imageView.image = [UIImage imageWithData:downloader.imageData];
[self.downloadsInProgress removeObjectForKey:[NSNumber numberWithInt:dID]];
}
}
PictureDownloader里面的cancelDownload方法
- (void)cancelDownload
{
[self.imageConnection cancel];
self.imageConnection = nil;
self.imageData = nil;
}
在 PictureDownloader 中的 connectionDidFinishedLoading
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if(self.picture)
{
self.picture.data = self.imageData;
NSError *error = nil;
[self.picture.managedObjectContext save:&error];
}
if(self.delegate != nil && [self.delegate respondsToSelector:@selector(didLoadPictureWithID:)] ) //place of failure
[self.delegate didLoadPictureWithID:self.ID];
self.imageData = nil;
self.imageConnection = nil;
}
有人可以给我一个提示,我该如何处理这个问题?
非常感谢您的帮助。