iPhone:如何减少图片的内存大小

时间:2011-02-03 12:13:19

标签: iphone uitableview

嗨我正在使用Twitter,我有图像问题,我有推文视图有UITableview,它包含所有推特用户照片,如果我在每个单元格中加载这些照片当我滚动UITableview时,它滚动非常慢请建议我减少照片的内存大小并快速滚动UITableView。

我听说缩略图可以减少内存大小,是吗。(如果不是我必须选择哪种方法以及缩放方法做什么),如果是这样,如何在此代码中执行此操作(表格视图)细胞代码)

 //Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

     static NSString *identifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];


    if(!cell) {

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewStyleGrouped reuseIdentifier:nil] autorelease];

    UIImageView *myImage = [[UIImageView alloc]initWithFrame:CGRectMake(6,10,58,60)] ;

    NSURL *url = [NSURL URLWithString:[(Tweet*)[tweetArray objectAtIndex:indexPath.row] image_url]]; //here Tweet is other class and image_url is method in the Tweet class

    NSData *data = [[NSData alloc] initWithContentsOfURL:url];

    [myImage setImage: [UIImage imageWithData:data]];

    [cell.contentView addSubview:myImage];

    [myImage release];  

    }

    return cell;

}

谢谢,

请建议我

3 个答案:

答案 0 :(得分:1)

表格视图滚动速度慢的原因是您正在尝试获取主线程上每个单元格的图像数据。 UI正在从URL获取图像数据时被阻止,据我所知,在加载表视图的同时在主线程上下载图像并不好。

您不必使用此方法,而是必须使用NSOperationQueue,NSOperation和NSThread将图像异步加载到适当的单元格。

如果您需要更多帮助或简单的代码(如2-3功能)下载图像异步...

以下是功能......

在解析/获取值的地方只调用[self startLoading];它将加载图像而不会阻止UI。

- (void) startLoading {
   NSOperationQueue *queue = [[[NSOperationQueue alloc]init]autorelease];
   NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(loadImagesInBackground) object:nil];
   [queue addOperation:op];
   [op release];
}

-(void) loadImagesInBackground {
      int index = 0;
      for (NSString urlString in [(Tweet*)[tweetArray objectAtIndex:indexPath.row] image_url]) {
           NSURL *url = [NSURL URLWithString:urlString];
           NSData *data = [[NSData alloc] initWithContentsOfURL:url];
           [myImageArray addObject: [UIImage imageWithData:data]];
           index++;
          if(index/3==0)
            [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
      }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

     static NSString *identifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];


    if(!cell) {

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewStyleGrouped reuseIdentifier:nil] autorelease];

    UIImageView *myImage = [[UIImageView alloc]initWithFrame:CGRectMake(6,10,58,60)] ;

    [myImage setImage: [myImageArray objectAtIndex:indexpath.row]];

    [cell.contentView addSubview:myImage];

    [myImage release];  

    }

    return cell;

}

答案 1 :(得分:0)

This article(下载没有线程的表的图像)可能有你的答案。 iOS开发库中还有this sample,它显示了如何尽快异步加载图像。

答案 2 :(得分:0)

您肯定想按照其他回答者的说法懒洋洋地和异步地下载图片。

您可能还希望将其大小调整为缩略图大小,并将其存储在较小的内存中。有关教程和实际可用的库代码,请参阅this article(向下滚动关于复制和粘贴开发的咆哮)。

编辑:您显然需要有关后台下载部分的更多帮助。我就是这样做的。

安装ASIHTTPRequest,这是第三方库,可以极大地简化HTTP客户端的工作。按照说明在项目中安装它,并确保将#include "ASIHTTPRequest.h"放在.m文件的顶部。

然后在tableView: cellForRowAtIndexPath:中,转到:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *identifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];


    if(!cell) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];

        UIImageView *myImage = [[UIImageView alloc]initWithFrame:CGRectMake(6,10,58,60)] ;

        [cell.contentView addSubview:myImage];
        [myImage release];
    }

    // so at this point you've got a configured cell, either created fresh
    // or dequeued from the table's cache.

    // what you DON'T have is a pointer to the uiimageview object. So we need to
    // go get it.

    UIImageView *theImageView;
    for (UIView *view in cell.contentView.subviews) {
        if ([view isKindOfClass:[UIImageView class]) {
            theImageView = view; 
            break;
        }
    }

    NSURL *url = [NSURL URLWithString:[(Tweet*)[tweetArray objectAtIndex:indexPath.row] image_url]]; //here Tweet is other class and image_url is method in the Tweet class

    ASIHTTPRequest *req = [ASIHTTPRequest requestWithURL:url];
    [req setCompletionBlock:^{
        NSData *data = [req responseData];

        // This is the UIImageView we extracted above:
        [theImageView setImage: [UIImage imageWithData:data]];
    }];

    // this will start the request in the background, and call the above block when done.
    [req startAsynchronous];

    }

    // Then return the cell right now, for the UITableView to render.
    // The image will get filled in later when it returns from the server.
    return cell;

}