我有一个系统从Web上加载很多大图像并将它们显示在自定义表格单元格中.在较旧的设备上,内存警告发生得非常快,所以我实现了一个从表中删除一些系统以试图解决这个问题的系统,但它不能很好地工作(很多图像被删除影响了UI).
所以我想我可以将所有图像加载到设备的缓存中,然后从那里加载它们 – 我已经实现了SDWebImage.这很好但我仍然没有解决内存分配的问题,因为图像仍然一直在显示因此留在记忆中 – 导致崩溃.
我想我需要实现一个系统,显示图像(来自缓存),如果单元格正在显示,如果单元格没有显示则隐藏它 – 我只是坚持如何构建这样的系统.
或者这不起作用?你真的可以通过从表格单元中删除图像来保持应用程序内存不足(并停止内存警告/崩溃)吗?或者我只需要继续使用我之前的解决方案并删除图像/单元格直到内存警告停止?
更新了代码
TableViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 0) { currentIndexPath = indexPath; ImageTableCell *cell = (ImageTableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; ImageDownloader *download = [totalDownloads objectAtIndex:[indexPath row]]; if (cell == nil) { cell = [[[ImageTableCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier] autorelease]; } cell.imageView.image = download.image; return cell; } return nil; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { int t = [totalDownloads count]; return t; }
ImageTableCell.m – 自定义单元格
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(Nsstring *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { self.frame = CGRectMake(0.0f,0.0f,320.0f,0.0f); self.contentView.frame = CGRectMake(0.0f,0.0f); self.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth); self.contentMode = UIViewContentModeScaletoFill; self.autoresizesSubviews = YES; self.contentView.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth); self.contentView.contentMode = UIViewContentModeScaletoFill; self.contentView.autoresizesSubviews = YES; [self.imageView drawRect:CGRectMake(0.0f,0.0f)]; self.imageView.contentMode = UIViewContentModeScaleAspectFill; self.imageView.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth); self.imageView.opaque = YES; } return self; }
ImageDownloader(实现SDWebImageManagerDelegate)
-(void) downloadImage // Comes from Model class { if (image == nil) { NSURL *url = [NSURL URLWithString:self.urlString]; SDWebImageManager *manager = [SDWebImageManager sharedManager]; // Remove in progress downloader from queue [manager cancelForDelegate:self]; if (url) { [manager downloadWithURL:url delegate:self retryFailed:YES]; } } } - (void)cancelCurrentimageLoad { [[SDWebImageManager sharedManager] cancelForDelegate:self]; } - (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)_image { self.image = _image; if ([self.delegate respondsToSelector:@selector(addImagetoModel:)]) [self.delegate addImagetoModel:self]; } - (void)webImageManager:(SDWebImageManager *)imageManager didFailWithError:(NSError *)error; { if ([self.delegate respondsToSelector:@selector(badImage)]) [self.delegate badImage]; }
解决方法
下载图像后,请勿将大图像保留在内存中.只需创建一个小尺寸的图像(缩略图)即可在tableview中显示,并将较大的图像写入某个目录.
您可以使用以下代码创建图像的缩略图.
CGSize size = CGSizeMake(32,32); UIGraphicsBeginImageContext(size); [yourImage drawInRect:CGRectMake(0,32,32)]; yourImage = UIGraphicsGetimageFromCurrentimageContext(); UIGraphicsEndImageContext();