Reputation: 3824
I am loading images to UITableViewCell
using the following function. But when I run my app with Debugger its getting crashed at [pool release]
whenever I scroll my UITableView
. What might I do to solve this? Thanks in advance.
- (void) loadImage{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
imageURL = [imageURL stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
//NSLog(@"img url cell**** %@",imageURL);
self.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
//self.image = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];
[pool release];
}
Upvotes: 1
Views: 307
Reputation: 58448
Quite a few things wrong here.
Firstly, your need of an autorelease pool quite clearly suggests that you're not doing this work on the main thread. UIKit is not thread-safe. Any UI work needs to be done on the main thread or undefined behaviour will occur, such as crashes.
Secondly, you're using what looks like a synchronous URL download of an image. Correct me if you're loading it from a file URL on disk. A synchronous image download is probably the reason why you've moved this into a separate thread, because it was blocking your UI right? One of the first things you should learn about network access it to never use a synchronous API on the main thread. Have you considered looking at the NSURLConnection
class in order to do an asynchronous download?
Thirdly, this needs to be re-architected so that the image download isn't directly linked to the display of the cell.
Displaying the table cell should be done on the main thread with the rest of the UI. When the cell is displayed, it should make a call to download the image asynchronously. The image download should be cached, and the cell should be informed via a delegate callback when the image download is complete. It should then display the image.
You can wrap these kind of things up in NSOperation
s and use NSOperationQueue
to manage them. Please, look at the documentation for these classes and checkout the example code for them to learn how to use them.
Upvotes: 0
Reputation: 8759
By the fact that you are using a NSAutoreleasePool I guess that load image is running in a thread that is not the main thread. Is this Correct? If that is the case you are making a UIKit invocation (self.image = ...) in this non-main thread and this is a possible source of the crash you are experiencing. All UIKit updates must be made in the main thread, since UIKit is not thread safe. Try replacing:
self.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
by
[self performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]] waitUntilDone:YES];
Notice I'm guessing the name of the setter is setImage:, you may need to correct if the setter selector has a different name that.
Upvotes: 5
Reputation: 12366
First of all, it is recommended to use [pool drain] instead of [pool release]. But I see another potential issue here: according to your code, you defined initially imageURL outside of your newly created autorelease pool (I don't see any alloc/init for imageURL, where is coming from? is it a table cell instance?) then you reassign imageURL with a newly allocated and autoreleased string: [imageURL stringByAddingPercentEscapesUsingEncoding:...]. Finally when you release the pool the new imageURL is release, so at the end what you had is a leak of the previously allocated imageURL. I can expect at this point that when exiting from the inner autorelease pool the run loop autorelease tries to release imageURL again (for example, but I need to see your code to fully understand) which has been deallocated.
Can you try to assign the result of stringByAddingPercentEscapesUsingEncoding: to a different name (e.g. myImageURL)?
Upvotes: 0