Add UIImage extensions for thread safe async loading and decoding

This commit is contained in:
Panayot Cankov
2016-05-13 16:47:59 +03:00
parent 68bdf905ce
commit 6201b36f0a
3 changed files with 41 additions and 24 deletions

View File

@@ -382,6 +382,7 @@
F98F5CC51CD0EFEA00978308 /* Release */, F98F5CC51CD0EFEA00978308 /* Release */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
}; };
F98F5CC61CD0EFEA00978308 /* Build configuration list for PBXNativeTarget "TNSWidgetsTests" */ = { F98F5CC61CD0EFEA00978308 /* Build configuration list for PBXNativeTarget "TNSWidgetsTests" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
@@ -390,6 +391,7 @@
F98F5CC81CD0EFEA00978308 /* Release */, F98F5CC81CD0EFEA00978308 /* Release */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
}; };
/* End XCConfigurationList section */ /* End XCConfigurationList section */
}; };

View File

@@ -20,4 +20,7 @@
*/ */
+ (UIImage*) tns_safeImageNamed: (NSString*) name; + (UIImage*) tns_safeImageNamed: (NSString*) name;
+ (void) tns_decodeImageWithData: (NSData*) data completion: (void (^) (UIImage*))callback;
+ (void) tns_decodeImageWidthContentsOfFile: (NSString*) file completion: (void (^) (UIImage*))callback;
@end @end

View File

@@ -6,24 +6,13 @@
// Copyright © 2016 Telerik A D. All rights reserved. // Copyright © 2016 Telerik A D. All rights reserved.
// //
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import <CoreGraphics/CoreGraphics.h>
#import "UIImage+TNSBlocks.h" #import "UIImage+TNSBlocks.h"
@implementation UIImage (TNSBlocks) @implementation UIImage (TNSBlocks)
static NSLock* image_lock_handle;
static dispatch_queue_t image_queue; static dispatch_queue_t image_queue;
static NSLock* image_lock_handle;
void image_lock() {
if (image_lock_handle) {
[image_lock_handle lock];
}
}
void image_unlock() {
if (image_lock_handle) {
[image_lock_handle unlock];
}
}
+ (void) initialize { + (void) initialize {
image_queue = dispatch_queue_create("org.nativescript.TNSWidgets.image", NULL); image_queue = dispatch_queue_create("org.nativescript.TNSWidgets.image", NULL);
@@ -35,20 +24,21 @@ void image_unlock() {
} }
} }
- (void) tns_decompressImage { - (void) tns_forceDecode {
UIGraphicsBeginImageContext(CGSizeMake(1, 1)); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
[self drawAtPoint:CGPointZero]; CGContextRef context = CGBitmapContextCreate(NULL, 1, 1, 8, 0, colorSpace, kCGImageAlphaPremultipliedFirst);
UIGraphicsEndImageContext(); CGContextDrawImage(context, CGRectMake(0, 0, 1, 1), [self CGImage]);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
} }
+ (void) tns_safeDecodeImageNamed: (NSString*) name completion: (void (^) (UIImage*))callback { + (void) tns_safeDecodeImageNamed: (NSString*) name completion: (void (^) (UIImage*))callback {
dispatch_async(image_queue, ^(void){ dispatch_async(image_queue, ^(void){
image_lock(); [image_lock_handle lock];
UIImage* image = [UIImage imageNamed: name]; UIImage* image = [UIImage imageNamed: name];
if (image) { [image_lock_handle unlock];
[image tns_decompressImage]; [image tns_forceDecode];
}
image_unlock();
dispatch_async(dispatch_get_main_queue(), ^(void) { dispatch_async(dispatch_get_main_queue(), ^(void) {
callback(image); callback(image);
}); });
@@ -56,10 +46,32 @@ void image_unlock() {
} }
+ (UIImage*) tns_safeImageNamed: (NSString*) name { + (UIImage*) tns_safeImageNamed: (NSString*) name {
image_lock(); [image_lock_handle lock];
UIImage* image = [UIImage imageNamed: name]; UIImage* image = [UIImage imageNamed: name];
image_unlock(); [image_lock_handle unlock];
return image; return image;
} }
+ (void) tns_decodeImageWithData: (NSData*) data completion: (void (^) (UIImage*))callback {
dispatch_async(image_queue, ^(void) {
UIImage* image = [UIImage imageWithData: data];
[image tns_forceDecode];
dispatch_async(dispatch_get_main_queue(), ^(void) {
callback(image);
});
});
}
+ (void) tns_decodeImageWidthContentsOfFile: (NSString*) file completion: (void (^) (UIImage*))callback {
dispatch_async(image_queue, ^(void) {
UIImage* image = [UIImage imageWithContentsOfFile: file];
[image tns_forceDecode];
dispatch_async(dispatch_get_main_queue(), ^(void) {
callback(image);
});
});
}
@end @end