views:

96

answers:

3

I'm loading 5 images from disk but I want the 1st image I read to show as soon as possible. Right now I do

UIImage *img = [UIImage imageWithContentsOfFile:path];

in a for loop but since imageWithContentsOfFile:path isn't blocking all 5 images wind up getting read from disk before the first one will appear (because they're all using up I/O). I confirmed this by just load one and it appeared on screen faster than if I load all 5.

I'd like to load the 1st image and block until its fully read and shown before loading the next 4 or load the 1st one and be notified when its done before loading the next 4 but I can't figure out a way to do it. None of the 'WithContentsOfFile' methods for data or image block and they don't notify or have delegate methods. Any suggestions?

Thanks

A: 

You want to load the image in the background and then have a call back when its done loading so you can display it...this way the block from reading the images wont effect you and you can display images while others are loading, or do whatever you like.. something like

-(void) getMyImage:(NSString*)path
then 
[self performSelectorInBackground:@selector(getMyImage) withObject:path];

you can also have a methods
-(void)didFinishLoadingImage:(UIImage*)image// which gets called in getMyImage when  the image is done loading...something like
[self performMethodInMainThread:@selector(didFinishloadingImage:)] etc...

You can use this to load the images as youd like.. you can pass extra variables in there so you can know which image you are loading, or come up with something to keep track, but using something like this should be able to solve your problem...

hope it helps

Daniel
Thanks Daniel but since imageWithContentsOfFile doesn't block the thread its run on it returns before the file is actually read. So doing it in the background doesn't help since the background thread completes before the file is finished reading. I tried doing it with 'detachNewThreadSelector' but all 5 'read' threads finished before the 1st image actually got data to show.
Shizam
ive read that the method loads the image lazily, but when it returns you should be able to display it fine i think...havent tried it tho
Daniel
A: 

AFAICS there is no way to guarantee that image data is in memory. The documentation on initWithContentsOfFile says that

This method loads the image data into memory and marks it as purgeable. If the data is purged and needs to be reloaded, the image object loads that data again from the specified path

So OS might free the memory at any moment and make your application to load image again from file. However, I think you can try to do some tricks like calling method that requires actual data. You can start by calling size of returned image. I'm not sure that size really needs all image data and is not cached. You might have to call something other methods on underlying CGImageRef. Something like CGImageGetBytesPerRow might do the trick. But I'd first start with size

iPhone beginner
A: 

You can ensure that the image is fully loaded from disk by first loading the image file into a NSData object and then initialize the image with the data:

NSError *err = nil;
NSData *data [NSData dataWithContentsOfFile:path 
                                    options:NSDataReadingUncached
                                      error:&err];
UIImage *img = [UIImage imageWithData:data];

Claus

Claus Broch
This is a good idea, I'll give it a go.
Shizam