+3  A: 

According to this mailing list post, UIGraphicsBeginImageContext isn't thread safe. The post hints that CGBitmapContextCreate and related functions are the safe way to do it.

http://osdir.com/ml/cocoa-dev/2009-10/msg00035.html

codewarrior
Yes it seems that was the problem. I used a @synchronized directive to make the image drawing part thread safe. Thanks.
kudor gyozo
+1  A: 

I think you're crashing because you're trying to access cells in the tableview that are not there.

Regardless of how long the logical table is, the visual tableview only holds enough cells to display the section of the logical table currently on screen. At the default row size, a table shows and therefore contains, only 9 to 10 cell objects. For example, if you have a logical table that is 100 rows long and your view is showing rows 11-20 the table only has 9 cell objects. If you show rows 89-98, it only has the exact same 9 cell objects. No matter which rows you display, you see the same 9 cell objects over and over again. The only thing that changes is the data they display.

If you try to access the cell for a logical row off screen, you won't get anything back. In your case, you try to access the 11th logical row but there is no 11th cell and there never will be.

I think you have some conceptual confusion because you're trying to store data in the tableview itself by setting the cell contents. This will not work because tableviews do not store any data beyond what is immediately displayed. When a tableview needs to display more rows as you scroll, it reuses the existing cell and its DataSource delegate changes the data that the existing cells display.

Instead of storing the images in the cells, you need to create a data model and store the images there. Then when the tableview scrolls, it will send tableview:cellForRowAtIndexPath: to its datasource delegate. The datasource delegate will then ask the data model for the data for the logical row, populate the reused cell and return it to the tableview.

TechZen
Yes i know, there are only as much cells allocated in memory as there are cell visible at once on the screen. But i verified that in handleDidFinishDownloadingImage. First i verify if the cell is visible. And if it's visible then i change the image in the cell. Otherwise i change only in the data source so that next time when it scrolls into view the image will be there.
kudor gyozo
A: 

Ok it seems it is solved thanks to codewarrior. This is the part that changed.

@synchronized(delegate)
{
    UIImage *resizedImage;
    UIGraphicsBeginImageContext(itemSize);
    CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
    [image drawInRect:imageRect];
    resizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    self.theImage = resizedImage; 
}
kudor gyozo