Hello everyone,
My project is a Thumbnail image gallery. I implemented it using a UITableView which has custom cells. In each cell there's 4 UIButtons which has the images. And the images are downloaded from the internet using their URLs.
The way I'm assigning the images to the buttons is using Jasarien's method described in this post. I'm basically creating a new NSOperation inside cellForRowAtIndexPath with the cell as the target and an action to call when it's done.
Everything works fine IF I'm scrolling through the table slowly, but if I scrolled fast it doesn't work and I'll explain the reason below, but take a look first at my implementation for cellForRowAtIndexPath:
ImageTableCell *cell = (ImageTableCell *)[tableView dequeueReusableCellWithIdentifier:@"4ImagesCell"];
if (cell == nil) {
NSLog(@"Cell is nil.");
cell = [[[ImageTableCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"4ImagesCell"] autorelease];
}
else {
NSLog(@"Cell is not nil.");
}
NSInteger imageIndex = indexPath.row * 4; // index for the first image in row
// loop through 4 images
for (int i = 1; i <= 4; i++) {
UIImage *img = [(UIButton *)[cell.contentView viewWithTag:i] currentImage]; // check if the cell has an image
if (img != nil && [img isKindOfClass:[UIImage class]]) {
NSLog(@"img is here.");
}
else {
NSURL *imgURL = [imageURLsArray objectAtIndex:imageIndex];
NSLog(@"img is not here. Creating a new download operation for URL: %@", imgURL);
ImageDownloadOperation *operation = [[ImageDownloadOperation alloc] initWithImageURL:imgURL forIndex:imageIndex target:cell action:@selector(doneLoadingImage:)];
[operationQueue addOperation:operation];
[operation release];
}
imageIndex++; //go to the next image
}
return cell;
If I scrolled slowly, each row will be initialized ("Cell is nil" will be printed). And if I scrolled fast "Cell is not nil" will be printed for the next rows to be displayed, and here the cell will have a problem because it's a dequeued cell.
The problem is my method of checking if a new download operation is needed or not inside the loop. I really can't figure out any other way to do it using NSOperation.
Is there a way to ensure that each row in the table gets initialized once? and if that's possible, would it be a memory problem if I have say 40, 50 or maybe 100 rows? If this would cause a memory problem, is there any other better way to implement this?
Any hints, tips or suggestions are highly appreciated. :)
Thanks in advance, Mota