Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS4 & background [UIImage setImage:]

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 ?

like image 752
Damien Debin Avatar asked Jun 28 '10 00:06

Damien Debin


People also ask

Is iOS 4 still supported?

With the launch of iOS 8 in 2014, the iPhone 4 no longer supported the iOS latest updates.

When did iOS 3 come out?

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.

Who made OldOS?

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.


3 Answers

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.

like image 157
Evadne Wu Avatar answered Oct 04 '22 05:10

Evadne Wu


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.

like image 36
Jaanus Avatar answered Oct 04 '22 05:10

Jaanus


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];
}
like image 44
James J Avatar answered Oct 04 '22 05:10

James J