Memory management for a convenience class to do asynchronous web requests
Inspired by Apple's LazyTables sample, I've just built myself a class called ImageLoader. It's agonizingly clever of me. And as is often the case when I'm agonizingly clever, I'm up against the limits of my wisdom about how to handle the memory of this object.
The thing gets instantiated from a UIViewController subclass inside viewDidLoad, thusly:
ImageDownloader *downloader = [[ImageDownloader alloc] init];
[downloader startDownloadWithImageView:self.theImageView
andImageURL:[NSURL URLWithString:myUrlString]];
Inside that method in ImageDownloader, I go:
开发者_Go百科-(void)startDownloadWithImageView:(UIImageView *)imageView
andImageURL:(NSURL *)url
{
self.theImageView = imageView;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
self.activeDownload = [NSMutableData data];
NSURLConnection *conn = [[NSURLConnection alloc]
initWithRequest:[NSURLRequest requestWithURL:url] delegate:self];
self.imageConnection = conn;
[conn release];
}
and my delegate method as a NSURLConnectionDelegate is (in pertinent part):
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
UIImage *image = [[UIImage alloc] initWithData:self.activeDownload];
theImageView.image = image;
[image release];
}
There's obviously all kinds of error checking it doesn't do yet, but you get the brilliance of it, right? I can now pass this thing a UIImageView and a NSURL and let it lazy-load the image asynchronously. Sa-weet!
So here's the question... How do I release downloader
? I don't think I can autorelease
from the ViewController where I create it, because I wouldn't expect NSURLConnection to call its delegate by the end of the run loop. Can I release self
at the end of connectionDidFinishLoading
? I've never seen that done, feels a little weird to release myself inside a method of myself.
My other thought is, I could make this a singleton and just not be concerned about it sticking around until we terminate. But I'd rather have the object come to life and go away cleanly.
Incidentally, the next step of my cleverness will be to add this functionality as a category of UIImageView. It'd be kind of neat to call [imageView asynchronouslyLoadImageFromURL:(NSURL *)url]
.
You could always put a [self retain]
in the -startDownloadWithImageView:andImageURL:
method and a [self release]
in the -connectionDidFinishLoading:
method. It's unconventional, obviously, but that would allow you to autorelease it after creating it without worrying about it being killed prematurely.
精彩评论