【问题标题】:lazy loading images in UITableView iPhone SDK在 UITableView iPhone SDK 中延迟加载图像
【发布时间】:2010-05-13 16:03:08
【问题描述】:

我需要为我的 tableview 中的图像实现延迟加载概念,以便最初向用户提供文本数据,然后提供图像。

我怎样才能在我的应用程序中实现它..需要帮助..请

提前致谢

世斌

【问题讨论】:

标签: iphone image lazy-loading


【解决方案1】:

我为我的一个项目创建的作品如下; 通过“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;
}

【讨论】:

  • 虽然我们感谢您在这篇文章中付出的努力,但请不要只是将其复制到每个适当的问题中。尝试为特定问题制定每个答案。谢谢!
【解决方案2】:

【讨论】:

  • 谢谢.. 我得到了这个,并将 IconDownloader 添加到我的项目中。但是 NSURLConnection:didReceiveData 委托方法不起作用。所以决定尝试另一种方式。你能帮我解决代理问题吗?
  • @Shibin:这听起来像是一个新问题,请使用“”按钮创建一个新问题,而不是在评论中寻求帮助。
  • NSURLConnection:didReceiveData delegate方法如果在主线程上实现则调用。
【解决方案3】:

我使用 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]);
}

【讨论】:

    猜你喜欢
    • 2010-11-10
    • 2011-10-26
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    • 1970-01-01
    • 2010-10-06
    相关资源
    最近更新 更多