2011-11-16 132 views
0

我建立我的表格视图的自定义单元格。我试图从互联网加载图片,为此,我正在使用异步下载。图像正在下载,但它没有在我的手机中显示此图像。我已经尝试在正常的视图中显示,并且工作正常。如果图像已经下载,或者如果我滚动表格视图并再次显示单元格,它也可以工作。有人知道发生了什么事吗?IPhone - 下载异步工作,但加载异步不要

代码:

DownloadImageManager.m

-(id)initWithImageName:(NSString *)imageAddress{ 
    self = [super initWithFrame:CGRectMake(10, 5, 100, 100)]; 
    if (self){ 
     self.urlString = imageAddress; 
     av = [[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease]; 
     av.frame = self.frame; 
     [av setBackgroundColor:[UIColor greenColor]]; 
     [self addSubview:av]; 
     [av startAnimating]; 
     [self checkImage]; 
    } 
    return self; 
} 

-(void)checkImage{ 
    bool isImageOnSysten = [self isImageOnFileSystem]; 
    if (isImageOnSysten) { 
     //If image is on the system, loads the image, it's working fine here 
     NSLog(@"CSantos: isImageOnSysten %@ is on system", self.urlString); 
    } else { 
     //here is the problem: 
     [self downloadImage]; 
    } 
} 

-(void)downloadImage{ 
    NSURL *url = [NSURL URLWithString:self.urlString]; 
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; 
    [request setDelegate:self]; 
    [request setAllowCompressedResponse:YES]; 
    [request setQueuePriority:NSOperationQueuePriorityLow]; 
    [request setDidFinishSelector:@selector(requestFinished:)]; 
    [request setDidFailSelector:@selector(requestFailed:)]; 
    [request setTimeOutSeconds:25]; 
    [request setNumberOfTimesToRetryOnTimeout:3]; 

    [request startAsynchronous]; 
} 

- (void)requestFinished:(ASIHTTPRequest *)request 
{ 
    NSData *responseData = [request responseData]; 
    NSArray *words = [self.urlString componentsSeparatedByString:@"/"]; 
    NSString *fileName = [words lastObject]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:fileName]; 
    NSError *error = nil; 
    [responseData writeToFile:writablePath options:NSDataWritingAtomic error:&error]; 
    NSLog(@"Write returned error: %@", [error localizedDescription]); 
    [av stopAnimating]; 
    [av removeFromSuperview]; 
} 

CellForProgram.m

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { 
    if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) { 

     textLabel = [[UILabel alloc]initWithFrame:CGRectMake(60, 31, 235, 40)] ; 
     [self.contentView addSubview:textLabel]; 

     photo = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 70, 70)]; 
     [photo setBackgroundColor:[UIColor blueColor]]; 
     photo.image = imagePhoto.image; 
     [self.contentView addSubview:photo]; 
    } 
    return self 

细胞来电

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

    static NSString *CellIdentifier = @"Cell"; 

    CellForProgram *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier] ; 
    if (cell == nil) { 
     cell = [[[CellForProgram alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    cell.textLabel.text = [speaker objectAtIndex:indexPath.row]; 

    DownloadImageManager *imageManager = [[DownloadImageManager alloc] initWithImageName:[images objectAtIndex:indexPath.row]]; 
    [cell.photo setImage:imageManager.image]; 
    return cell; 
} 

回答

0

我告诉我不需要在DownloadImageManager上做这种改变!但是,谢谢你的帮助,它帮助我完成了其他的事情!

CellForProgram.m

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { 
    if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) { 

     textLabel = [[UILabel alloc]initWithFrame:CGRectMake(60, 31, 235, 40)] ; 
     [self.contentView addSubview:textLabel]; 

     imagePhoto = [[DownloadImageManager alloc] initWithImageName:imageAdress.text]; 
     [self.contentView addSubview:imagePhoto]; 
    } 
    return self 
} 

DownLoadImageManager.m:添加此方法

-(void)changeImage:(NSString *)newImage{ 
    self.urlString = newImage; 
    [self checkImage]; 
} 

细胞来电

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

    static NSString *CellIdentifier = @"Cell"; 

    CellForProgram *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier] ; 
    if (cell == nil) { 
     cell = [[[CellForProgram alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    cell.textLabel.text = [speaker objectAtIndex:indexPath.row]; 

    [cell.imagePhoto changeImage:[images objectAtIndex:indexPath.row]]; 
    return cell; 
} 
1

你不与指针正常工作。

当您致电[cell.photo setImage:imageManager.image];并且图像不存在时,您将它指向零或随机存储器空间。

您需要在DownloadImageManager类上创建一个指向您的单元格的指针,以便在图像完成下载时更新单元格。

下面是我建议:

  • 创建指向您的自定义的UITableViewCell
  • 类不要设置上的tableView的图像DownloadImageManager属性:的cellForRowAtIndexPath:选择。相反,请直接在DownloadImageManager上设置它。

这里有一个简单的修改代码:

细胞来电

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

    static NSString *CellIdentifier = @"Cell"; 

    CellForProgram *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier] ; 
    if (cell == nil) { 
     cell = [[[CellForProgram alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    cell.textLabel.text = [speaker objectAtIndex:indexPath.row]; 

    DownloadImageManager *imageManager = [[DownloadImageManager alloc] initWithImageName:[images objectAtIndex:indexPath.row] andCell:cell]; 
    return cell; 
} 

DownloadImageManager.m

-(id)initWithImageName:(NSString *)imageAddress andCell:(CellForProgram*)cell{ 
    self = [super initWithFrame:CGRectMake(10, 5, 100, 100)]; 
    if (self){ 
     self.urlString = imageAddress; 
     self.cell = cell; 
     av = [[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease]; 
     av.frame = self.frame; 
     [av setBackgroundColor:[UIColor greenColor]]; 
     [self addSubview:av]; 
     [av startAnimating]; 
     [self checkImage]; 
    } 
    return self; 
} 

-(void)checkImage{ 
    bool isImageOnSysten = [self isImageOnFileSystem]; 
    if (isImageOnSysten) { 
     //If image is on the system, loads the image, it's working fine here 
     NSLog(@"CSantos: isImageOnSysten %@ is on system", self.urlString); 
     cell.photo = self.image; 
    } else { 
     //here is the problem: 
     [self downloadImage]; 
    } 
} 

-(void)downloadImage{ 
    NSURL *url = [NSURL URLWithString:self.urlString]; 
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; 
    [request setDelegate:self]; 
    [request setAllowCompressedResponse:YES]; 
    [request setQueuePriority:NSOperationQueuePriorityLow]; 
    [request setDidFinishSelector:@selector(requestFinished:)]; 
    [request setDidFailSelector:@selector(requestFailed:)]; 
    [request setTimeOutSeconds:25]; 
    [request setNumberOfTimesToRetryOnTimeout:3]; 

    [request startAsynchronous]; 
} 

- (void)requestFinished:(ASIHTTPRequest *)request 
{ 
    NSData *responseData = [request responseData]; 
    NSArray *words = [self.urlString componentsSeparatedByString:@"/"]; 
    NSString *fileName = [words lastObject]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:fileName]; 
    NSError *error = nil; 
    [responseData writeToFile:writablePath options:NSDataWritingAtomic error:&error]; 
    NSLog(@"Write returned error: %@", [error localizedDescription]); 
    [av stopAnimating]; 
    [av removeFromSuperview]; 

    cell.photo = self.image; 
} 

这应该让你去。如果您需要澄清,请务必留言,我会尽快回复。

编辑:作为替代方案,实现对DownloadImageManager的委托方法...

一下添加到DownloadImageManager。H:

@protocol DownloadImageManagerDelegate <NSObject> 
@optional 
- (void)DownloadFinished:(DownloadImageManager*)manager; 
@end 

取而代之的是CellForProgram的,使用DownloadImageManager协议,与此构造为例:

,改变你的requestFinished的实现:像这样:

- (void)requestFinished:(ASIHTTPRequest *)request 
{ 
    NSData *responseData = [request responseData]; 
    NSArray *words = [self.urlString componentsSeparatedByString:@"/"]; 
    NSString *fileName = [words lastObject]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:fileName]; 
    NSError *error = nil; 
    [responseData writeToFile:writablePath options:NSDataWritingAtomic error:&error]; 
    NSLog(@"Write returned error: %@", [error localizedDescription]); 
    [av stopAnimating]; 
    [av removeFromSuperview]; 

    if ([delegate respondsToSelector:@selector(DownloadFinished:)]) { 
     [delegate DownloadFinished:self]; 
    } 
} 

然后,使您的细胞达到给定的协议,如下所示:

- (void)DownloadFinished:(DownloadImageManager*)manager { 
    this.photo = manager.image; 
} 

这样您就可以随意地将您的功能保留在DownloadImageManager上。

+0

伴侣,这是不是一个真正的好主意。这正在改变DownloadImageManager,我可以在这个单元格中使用它。如果我尝试在其他地方使用,我会收到很多错误消息。 – Claudio

+0

@Claudio我向协议/委托理念添加了答案,您可以使用它来保持您的下载类的功能,并且仍然可以解决您的问题。 –

+0

我刚刚说过:DownloadImageManager在所有其他接口中工作,但那一个(cell/tableview)。这不是课堂上的问题,而是我在这里使用的方式。 – Claudio