This article explains the following:
- UIImageView load remote image
- UIImageView refresh image periodically
- TTImageView refresh image
- Reload UIImageView from background thread
If you want to add an image as an subview, you can use UIImageView easily. However, if the image is from remote server, you can create UIImageView using the following code:
UIImageView *imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(2, 2, 10, 10)] autorelease]; NSURL *url = [NSURL URLWithString:@"http://your_image_url"]; UIImage *chart = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]]; [url release]; imageView.image = chart;
However, the main problem with this code is that the downloading of image by NSURL is not asynchronous. The iphone UI is handled in main thread, if this fetch is synchronous, it means that the UI is being blocked while the image is downloaded. If the downloading happens to be very slow, you are going to have very laggy UI. The fix to it is to running it in background thread.
//assume imageView is an instance variable
imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(2, 2, 10, 10)] autorelease];
[NSThread detachNewThreadSelector:@selector(updateChart) toTarget:self withObject:nil];
- (void) updateChart {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *url = [NSURL URLWithString:@"http://your_image_url"];
UIImage *chart = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
[url release];
imageView.image = chart;
[pool release];
}
By detaching the process of downloading image from main thread, it won’t block the UI. In the case that you want to update the image periodically, you can create a timer and call the updateChart periodically.
[NSTimer scheduledTimerWithTimeInterval:10 target:self selector: @selector(updateChartInBackground) userInfo:nil repeats:YES];
- (void) updateChartInBackground {
[NSThread detachNewThreadSelector:@selector(updateChart) toTarget:self withObject:nil];
}
On the other hand, TTImageView from three20 is another choice to load image and the loading is asynchronous.
TTImageView* chart = [[[TTImageView alloc] initWithFrame:CGRectMake(2,2,30, 30)] autorelease]; chart.backgroundColor = [UIColor clearColor]; chart.defaultImage = nil; chart.urlPath = @"http://test.com/test.png";
This is pretty simple and elegant. However, I have problem when I try to load the image periodically. This is what I have done:
//assume chart is an instance variable, so it is accessible in other methods
[chart performSelectorOnMainThread:@selector(updateChart) withObject:nil waitUntilDone:NO];
- (void) updateChart {
//remove the image from cache in case the loading is from cache
[[TTURLCache sharedCache] removeURL:@"http://your_image_url" fromDisck:YES];
[chart reload];
}
However, in the app delegate, i have the following two lines to make sure the initial image loaded is not from cache and subsequent image request is not cached:
[TTURLCache sharedCache].disableImageCache = YES; [[TTURLCache sharedCache] removeAll:YES];
However, i found out that the image is still cached somehow. That’s why I have the removeURL:fromDisck method in the updateChart method.
Even, i do this, the chart is not reloaded. By checking [chart isLoading] it always gives me true, which means the request is not finished. I have spent quite some time on this, and can’t figure out what’s wrong. So I gave up on TTImageView and use UIImageView instead, which can achieve the same effect.


