Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I used @jasamer's SwapTest UIImage category to force load my large UIImage (about 3000x2100 px) in a worker thread (with NSOperationQueue). This reduces the stutter time when setting the image into the UIImageView to an acceptable value (about 0.5 sec on iPad1).</p> <p>Here is SwapTest UIImage category... thanks again @jasamer :)</p> <p>UIImage+ImmediateLoading.h file</p> <pre><code>@interface UIImage (UIImage_ImmediateLoading) - (UIImage*)initImmediateLoadWithContentsOfFile:(NSString*)path; + (UIImage*)imageImmediateLoadWithContentsOfFile:(NSString*)path; @end </code></pre> <p>UIImage+ImmediateLoading.m file</p> <pre><code>#import "UIImage+ImmediateLoading.h" @implementation UIImage (UIImage_ImmediateLoading) + (UIImage*)imageImmediateLoadWithContentsOfFile:(NSString*)path { return [[[UIImage alloc] initImmediateLoadWithContentsOfFile: path] autorelease]; } - (UIImage*)initImmediateLoadWithContentsOfFile:(NSString*)path { UIImage *image = [[UIImage alloc] initWithContentsOfFile:path]; CGImageRef imageRef = [image CGImage]; CGRect rect = CGRectMake(0.f, 0.f, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); CGContextRef bitmapContext = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), CGImageGetColorSpace(imageRef), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little ); //kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little are the bit flags required so that the main thread doesn't have any conversions to do. CGContextDrawImage(bitmapContext, rect, imageRef); CGImageRef decompressedImageRef = CGBitmapContextCreateImage(bitmapContext); UIImage* decompressedImage = [[UIImage alloc] initWithCGImage: decompressedImageRef]; CGImageRelease(decompressedImageRef); CGContextRelease(bitmapContext); [image release]; return decompressedImage; } @end </code></pre> <p>And this is how I create NSOpeationQueue and set the image on main thread...</p> <pre><code>// Loads low-res UIImage at a given index and start loading a hi-res one in background. // After finish loading, set the hi-res image into UIImageView. Remember, we need to // update UI "on main thread" otherwise its result will be unpredictable. -(void)loadPageAtIndex:(int)index { prevPage = index; //load low-res imageViewForZoom.image = [images objectAtIndex:index]; //load hi-res on another thread [operationQueue cancelAllOperations]; NSInvocationOperation *operation = [NSInvocationOperation alloc]; filePath = [imagesHD objectAtIndex:index]; operation = [operation initWithTarget:self selector:@selector(loadHiResImage:) object:[imagesHD objectAtIndex:index]]; [operationQueue addOperation:operation]; [operation release]; operation = nil; } // background thread -(void)loadHiResImage:(NSString*)file { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSLog(@"loading"); // This doesn't load the image. //UIImage *hiRes = [UIImage imageNamed:file]; // Loads UIImage. There is no UI updating so it should be thread-safe. UIImage *hiRes = [[UIImage alloc] initImmediateLoadWithContentsOfFile:[[NSBundle mainBundle] pathForResource:file ofType: nil]]; [imageViewForZoom performSelectorOnMainThread:@selector(setImage:) withObject:hiRes waitUntilDone:NO]; [hiRes release]; NSLog(@"loaded"); [pool release]; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload