0

So this may be sort of difficult to explain, but I'll do my best. This problem might take a few steps to solve too.

This code appears in a tableviewcell, so it's ran every time the cell comes on screen:

[cell.cellContent.thumbnails removeAllObjects];

if ([self.cellThumbnailCache objectForKey:[NSNumber numberWithInt:indexPath.row]]) {
    cell.cellContent.thumbnails = [self.cellThumbnailCache objectForKey:[NSNumber numberWithInt:indexPath.row]];
    [cell.cellContent setNeedsDisplay];
}
else {

    //First it removes all the existing UIImages from the cell.cellContent.thumbnails mutable array.
    int i = 0;

    while (i < numberOfThumbnailsToDraw) {
        Media *media = [entryNewMoc.media objectAtIndex:i];
        UIImage *image = [media getThumbnail];

        [newMoc save:nil];

        [cell.cellContent.thumbnails addObject:image];
        i++;
    }

    //Then it goes through getting UIImages and adding them to the array.
    [self.cellThumbnailCache setObject:cell.cellContent.thumbnails forKey:[NSNumber numberWithInt:indexPath.row]];
    [cell.cellContent setNeedsDisplay];

    //Then it all gets drawn in setNeedsDisplay.
}        

The problem is, when it comes back round to removing all the objects, it seems to remove the actual UIImages from record, because an NSLog on the thumbnailsCache shows the entry to be empty. It's the removeAllObjects line that does it, but if it's kept then it just keeps adding more media to the cell.

WrightsCS
  • 50,551
  • 22
  • 134
  • 186
Andrew
  • 15,935
  • 28
  • 121
  • 203
  • Store image in document directory if not stored eitherwise obtain that image from it. Image will be in this format image_0.png, image_1.png,....... – Paresh Navadiya Jun 12 '12 at 02:37
  • First, that `if`/`else` can be simplified: `cell.cellContent.thumbnails = [self.cellThumbnailCache objectForKey:[NSNumber numberWithInt:indexPath.row]]; if( !cell.cellContent.thumbnails ){ // Do stuff in else branch` Second, why are you using a dictionary if the key is just an `NSNumber` constructed from an integer? You can use an array. Also, why use a `while` loop to do a `for`'s job? – jscs Jun 12 '12 at 02:48
  • @JoshCaswell Using a dictionary because the cells aren't nessaserily loaded in order, so you can't go adding objectAtIndex:20 when 14-19 don't exist. While instead of for.. I always used whiles, never got comfortable with fors. As far as I'm aware it does the same job, I'm just more comfortable sticking with it right now. – Andrew Jun 12 '12 at 09:18
  • Ah, a dictionary subbing for a sparse array -- got it. – jscs Jun 12 '12 at 18:07

1 Answers1

2

Try assign simple copy, like i.e.:

[self.cellThumbnailCache setObject:[NSSet setWithSet:cell.cellContent.thumbnails] ....
Michał Kreft
  • 548
  • 3
  • 16
  • Nope, doesn't work. The pointers are still going to the same location, so it still deletes the place they're pointing to, I guess. – Andrew Jun 12 '12 at 02:27
  • @Andrew, if this doesn't work, then something else is wrong. You're giving the `cellThumbnailCache` dictionary a pointer to the `thumbnails` mutable set. If you then send `removeAllObjects` to the set, you will see an empty set whether you access it via `thumbnails` or the dictionary. If you make a _copy_ when you put it into the dictionary, though, then the dictionary has its own version. The objects in the set will be retained by the copy and live on. – jscs Jun 12 '12 at 02:55
  • I think you also have to modify this line: cell.cellContent.thumbnails = [self.cellThumbnailCache objectForKey:[NSNumber numberWithInt:indexPath.row]]; so here you also have to assign a copy, because otherwise images will be released as this is the only reference to them – Michał Kreft Jun 12 '12 at 06:49
  • But honestly the devil is in the design here, maybe [cell.cellContent.thumbnails removeAllObjects]; is simply not needed at all since you are overwriting it anyway; I would try to make it less complicated – Michał Kreft Jun 12 '12 at 06:53
  • @ride.inc I think you might be right. I just made a new array on the while loop, then overwrote the value instead. Thanks guys. – Andrew Jun 12 '12 at 09:19