IPhone - 下载异步工作,但加载异步不要
我建立我的表格视图的自定义单元格。我试图从互联网加载图片,为此,我正在使用异步下载。图像正在下载,但它没有在我的手机中显示此图像。我已经尝试在正常的视图中显示,并且工作正常。如果图像已经下载,或者如果我滚动表格视图并再次显示单元格,它也可以工作。有人知道发生了什么事吗?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;
}
我告诉我不需要在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;
}
你不与指针正常工作。
当您致电[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上。
伴侣,这是不是一个真正的好主意。这正在改变DownloadImageManager,我可以在这个单元格中使用它。如果我尝试在其他地方使用,我会收到很多错误消息。 – Claudio
@Claudio我向协议/委托理念添加了答案,您可以使用它来保持您的下载类的功能,并且仍然可以解决您的问题。 –
我刚刚说过:DownloadImageManager在所有其他接口中工作,但那一个(cell/tableview)。这不是课堂上的问题,而是我在这里使用的方式。 – Claudio