Вы неправильно работаете с указателями.
Когда вы звоните [cell.photo setImage:imageManager.image];
, а изображение не существует, вы указываете его на ноль или на случайную область памяти.
Вам необходимо создать указатель на вашу ячейку в классе DownloadImageManager, чтобы вы могли обновить ячейку после завершения загрузки изображения.
Вот что я рекомендую:
- Создайте свойство в DownloadImageManager, которое указывает на ваш пользовательский класс UITableViewCell
- Не устанавливайте изображение на tableView: cellForRowAtIndexPath: селектор. Вместо этого установите его непосредственно в DownloadImageManager.
Вот простая модификация вашего кода:
Cell Caller
- (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 с примером этого конструктора:
-(id)initWithImageName:(NSString *)imageAddress andDelegate:(DownloadImageManagerDelegate*)delegate
И измените вашу реализацию 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 так, как хотите.