我创建了一个显示内容的六个“单元格”的网格视图。在每个单元格中,从Web加载图像。此网格有多个页面(用户通过向上/向下滑动来查看下一组单元格。)
每个单元格都有自己的视图控制器。当这些视图控制器加载时,它们使用我加载的ImageLoader类并显示图像。这些视图控制器实现了一个ImageLoaderDelegate,它具有一个在图像加载完成后调用的方法。
ImageLoader在后台线程上工作,然后在加载完成后通知其委托,将图像传递给委托方法。
麻烦的是,如果用户在图像加载完成之前移动到网格内容的下一页(释放使用ImageLoaders的GridCellViewControllers),则应用程序崩溃。我怀疑这是因为沿着这条线,异步方法完成并尝试通知其委托但不能因为它已被释放。
这里有一些代码可以提供更好的图片:
GridCellViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
// ImageLoader
_loader = [[ProductImageLoader alloc] init];
_loader.delegate = self;
if(_boundObject)
[_loader loadImageForProduct:_boundObject];
}
//ImageLoaderDelegate method
- (void) imageDidFinishLoading: (UIImage *)image {
[_imgController setImage:image];
}
ProductImageLoader.m
- (void) loadImageForProduct: (Product *) product {
// Get image on another thread
[NSThread detachNewThreadSelector:@selector(getImageForProductInBackground:) toTarget:self withObject:product];
}
- (void) getImageForProductInBackground: (Product *) product {
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
HttpRequestLoader *tempLoader = [[HttpRequestLoader alloc] init];
NSURL *tempUrl = [product getImageUrl];
NSData *imageData = tempUrl ? [tempLoader loadSynchronousDataFromAddress:[tempUrl absoluteString]] : nil;
UIImage *image = [[UIImage alloc] initWithData:imageData];
[tempPool release];
if(delegate)
[delegate imageDidFinishLoading:image];
}
该应用与EXC_BAD_ACCESS崩溃。
免责声明:代码略有修改,专注于手头的问题。
答案 0 :(得分:1)
有一半时间我在这里问一个问题,不久后我想出了一个解决方案。写下问题可能是解决方案的90%。
无论如何,这就是我所做的,并且可能会有所改进,因为我仍然怀疑这些线程。
事实证明问题是委托方法仍然会触发(imageDidFinishLoading),但委托已经被释放。通过在GridCellViewController.m中释放时将委托显式设置为nil,消息永远不会触发。
GridCellViewController.m
- (void) dealloc {
if(_loader) {
_loader.delegate = nil;
[_loader release];
}
}