Adam Zarn Adam Zarn - 1 month ago 6
Objective-C Question

App Crashes when too many images are in TableView

I have a table that I am populating with information stored in Runner Objects. Each Runner object has a property called fileName that corresponds to an image saved in the document directory.

If I start with an empty table, I can add runners and their photos just fine until I reach about 8 runners. When I try to add a photo for the 8th or so runner, the app crashes. It seems to be a memory issue, but I don't see how this can be when all I'm storing locally are references to images in the directory.

I pass a runner object to my set up cell method in my RunnerCell class and set up the cell like so:

if (currentRunner.fileName != nil) {
if ([manager fileExistsAtPath:fullPath]){

UIImage *originalImage = [[UIImage alloc] initWithContentsOfFile:fullPath];

if ([currentRunner.photoOrientation isEqual: @"portrait"]) {
CGImageRef imageRef = [originalImage CGImage];
UIImage *rotatedImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationRight];
self.runnerImageView.image = rotatedImage;
} else {
self.runnerImageView.image = originalImage;
}
self.addPhotoLabel.hidden = true;
}
}

Answer

As per documentation states that you mustn't load image to a UITableViewCell on main thread. That is why your app is crashing. Because when you load image on main thread it became too much laggy when you scroll because dequereusable cell reassign cell and again load image for upcoming indexpath's cell and until the image loads it block the main thread which cause laggy behaviour of tableview.

Please load your cached image in a background thread. use this code.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {

    if ([currentRunner.photoOrientation isEqual: @"portrait"]) {
            CGImageRef imageRef = [originalImage CGImage];
            UIImage *rotatedImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:UIImageOrientationRight];
        dispatch_sync(dispatch_get_main_queue(), ^(void) {
        self.runnerImageView.image = rotatedImage;
    });
    } else {
          dispatch_sync(dispatch_get_main_queue(), ^(void) {
        self.runnerImageView.image = originalImage;
    });
    }

});