How to read an image from disk and block until its read?
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开发者_StackOverflow 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
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
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
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
精彩评论