【发布时间】:2010-05-13 16:03:08
【问题描述】:
我需要为我的 tableview 中的图像实现延迟加载概念,以便最初向用户提供文本数据,然后提供图像。
我怎样才能在我的应用程序中实现它..需要帮助..请
提前致谢
世斌
【问题讨论】:
-
见 EGOImageLoading,developers.enormego.com/view/…
标签: iphone image lazy-loading
我需要为我的 tableview 中的图像实现延迟加载概念,以便最初向用户提供文本数据,然后提供图像。
我怎样才能在我的应用程序中实现它..需要帮助..请
提前致谢
世斌
【问题讨论】:
标签: iphone image lazy-loading
我为我的一个项目创建的作品如下; 通过“UITableViewCell+Async.h”中的类别扩展 UITableViewCell 类 (如果您不确定 Obj C 中的类别事物是什么,请查看一些示例)
@interface UITableViewCell (Async)
-(void)loadAsyncImage:(NSString*)url withIndex:(NSInteger)index inWidth:(NSInteger)width inHeight:(NSInteger)height;
-(void)loadAsyncBackground:(NSMutableArray*)parameters;
@end
然后在实现文件“UITableViewCell+Async.m”中
#import "UITableViewCell+Async.h"
@implementation UITableViewCell (Async)
-(void)loadAsyncImage:(NSString*)url
withIndex:(NSInteger)index
inWidth:(NSInteger)width
inHeight:(NSInteger)height {
NSMutableArray* parameters = [NSMutableArray arrayWithCapacity:2];
[parameters addObject:url];
[parameters addObject:[NSNumber numberWithInteger:index]];
[parameters addObject:[NSNumber numberWithInteger:width]];
[parameters addObject:[NSNumber numberWithInteger:height]];
self.imageView.tag = index;
[self performSelectorInBackground:@selector(loadAsyncBackground:) withObject:parameters];
}
-(void)loadAsyncBackground:(NSMutableArray*)parameters {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString* url = [parameters objectAtIndex:0];
NSInteger index = [[parameters objectAtIndex:1] integerValue];
NSInteger width = [[parameters objectAtIndex:2] integerValue];
NSInteger height = [[parameters objectAtIndex:3] integerValue];
UIImage* image = [Utils getImageResized:url inSize:CGSizeMake(width, height)];
if (self.tag==index) {
self.imageView.image = image;
[self setNeedsLayout];
}
[pool release];
}
@end
这基本上为 UITableViewCell 添加了一个功能,可以在新的后台线程中加载图像,调整图像大小并将其设置为 imageview。检查添加的标签以查看单元格是否仍在等待图像,因为它可以重复使用,并且图像的另一个线程可能正在为该重复使用的单元格下载另一个图像...
上面代码中的函数,签名为;
+(UIImage*)getImageResized:(NSString*)url inSize:(CGSize)size;
检查图像的本地缓存,如果不在缓存中,则从网络下载图像,将其保存到本地缓存,将图像调整为给定大小并返回图像,所有这些都在同步(阻塞)方法调用中完成.由于这已经是后台线程,因此为此操作阻止它没有害处。当该方法返回图像时,如果它仍然具有相同的标签(不重复用于其他行),则将其设置为单元格的图像视图
在 cellForRowAtIndexPath 方法中你可以添加新的类别,你应该完成了;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"......."];
if (cell == nil) {
................
}
................
[cell loadAsyncImage:deal.logo withIndex:indexPath.row inWidth:40 inHeight:40];
................
return cell;
}
【讨论】:
【讨论】:
NSURLConnection:didReceiveData delegate方法如果在主线程上实现则调用。
我使用 ASINetworkQueue 进行延迟加载。
在.h文件中
#import "ASINetworkQueue.h"
并定义一个变量
//array contains url address of images and a variable of ASINetworkQueue;
NSMutableArray *arrImg;
ASINetworkQueue *queue;
在 .m 文件中
static int rowNo = 0;
- (void)downloadImages{
if(queue == nil){
queue = [[[ASINetworkQueue alloc] init] autorelease];
}
for(NSString* urlString in arrImg)
{
NSURL *url = [NSURL URLWithString:urlString];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestWentWrong:)];
[queue addOperation:request];
}
[queue go];
}
- (void)requestDone:(ASIHTTPRequest*)req{
for (int i = 0; i < [arrImg count]; i++) {
NSMutableString *d = [[NSMutableString alloc] init];
d = [arrImg objectAtIndex:i];
//comparing the url to get correct row no of cell
if([[req.url absoluteString] isEqualToString:d]){
rowNo = i;
break;
}
}
//creating a cell with rowNo
NSIndexPath *index = [NSIndexPath indexPathForRow:rowNo inSection:0];
UITableViewCell *cell = (UITableViewCell *)[roomTable cellForRowAtIndexPath:index];
UIImageView *v = (UIImageView *)[cell.contentView viewWithTag:10];
v.image = [UIImage imageWithData:[req responseData]];
[cell release];
cell = nil;
[v release];
v = nil;
}
- (void)requestWentWrong:(ASIHTTPRequest*)req{
for (int i = 0; i < [arrImg count]; i++) {
NSMutableString *d = [[NSMutableString alloc] init];
d = [arrImg objectAtIndex:i];
//comparing the url to get correct row no of cell
if([[req.url absoluteString] isEqualToString:d]){
rowNo = i;
break;
}
}
NSLog(@"No data for cell : %d",rowNo);
NSLog(@"Request returned an error %@",[req error]);
}
【讨论】: