Up to iOS 3.2, I used this kind of code to load UIImageView
image in background, and it worked fine...
Code:
- (void)decodeImageName:(NSString *)name
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *newImage = [UIImage imageNamed:name];
[myImageView setImage:newImage];
[pool release];
}
...
[self performSelectorInBackground:@selector(decodeImageName:) withObject:@"ID"]
... even if [UIImageView setImage:]
was not thread-safe !
But since iOS 4, it doesn't work any more... Images appear on screen two seconds after setImage
call. And if I do a [myImageView performSelectorOnMainThread:@selector(setImage:) withObject:newImage waitUntilDone:YES]
instead of [myImageView setImage:newImage]
, images appear immediately but seem to be re-decoded again on-the-fly (ignoring the previous [UIImage imageNamed:]
which should have already decoded the image data), causing a pause on my main thread... Even if documentation says The underlying image cache is shared among all threads..
Any thought ?
With the launch of iOS 8 in 2014, the iPhone 4 no longer supported the iOS latest updates.
iPhone OS 3 is the third major release of the iOS mobile operating system developed by Apple Inc., succeeding iPhone OS 2. It was announced on March 17, 2009, and was released on June 17, 2009.
Things were better back then, weren't they? If you fancy a reality check, you can now revisit the old days of iPhone with the suitably named OldOS. It's the brainchild of teenage developer Zane Kleinberg – who would have been a mere child when the iPhone 4 originally rocked up.
Don’t do it in the background! It’s not thread-safe. Since an UIImageView
is also an NSObject
, I think that using -[performSelectorOnMainThread:withObject:waitUntilDone:]
on it might work, like:
[myImageView performSelectorOnMainThread:@selector(setImage:) withObject:newImage waitUntilDone:NO];
And it’s UIImage
which is newly made thread-safe. UIImageView
is still not thread-safe.
performSelectorInBackground:
runs a selector in a background thread. Yet setImage: is a UI function. UI functions should only be run on the main thread. I do not have insight into the particular problem, but this is the first gut feel about this code, and it may be that iOS4 handles the (non-supported) mechanism of running UI functions in background threads somehow differently.
If you're using iOS 4.0, you should really consider reading up on blocks and GCD. Using those technologies, you can simply replace your method with:
- (void)decodeImageName:(NSString *)name
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *newImage = [UIImage imageNamed:name];
dispatch_async(dispatch_get_main_queue(), ^{
[myImageView setImage:newImage];
}
[pool release];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With