I am trying to optimize the load in my application, in fact, I have a lot of images that loaded in my application, and I spend a lot of time waiting for a view controller to ope
You can try something like this!....
dispatch_queue_t checkInQueueForPostImage = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(checkInQueueForPostImage, ^{
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:postAndCheckInDetails.postImageURL]]];
dispatch_sync(dispatch_get_main_queue(), ^{
if (image!=nil) {
[uploadImage setImage:image];
}
[cell setNeedsLayout];
});
});
To enable the app while getting the images from server and disable block while loading the images try to use UIImageView+AFNetworking library to load the image from server asynchronously AFNetworking
NSString *imageUrl = [[dict objectForKey:@"photo"] objectForKey:@"url"];
UIImageView *myImage = [[UIImageView alloc] init];
[myImage setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:@"PlaceHolder.png"]];
Just add this library and include the UIImageView+AFNetworking so you can use the new UIImageView Category imageWithUrl
you can check this tutorial on NSOperationQueue and this on GCD doing exactly same. Also you can try using:
// Block variable to be assigned in block.
__block NSData *imageData;
dispatch_queue_t backgroundQueue = dispatch_queue_create("com.razeware.imagegrabber.bgqueue", NULL);
// Dispatch a background thread for download
dispatch_async(backgroundQueue, ^(void) {
imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *imageLoad;
imageLoad = [[UIImage alloc] initWithData:imageData];
// Update UI on main thread
dispatch_async(dispatch_get_main_queue(), ^(void) {
imageView.image = imageLoad;
});
});
Use IDAsyncImageView.h
//////////////////////////////////////
IDAsyncImageView.h
/////////////////////////////////////
@interface IDAsyncImageView : NSObject
@property (nonatomic, strong) NSCache *cache;
+ (instancetype)instance;
- (void)loadImageView:(UIImageView*)imageView withURLString:(NSString *)urlString;
@end
//////////////////////////////////////
IDAsyncImageView.m
/////////////////////////////////////
#import "IDAsyncImageView.h"
@implementation IDAsyncImageView
+ (instancetype)instance
{
static IDAsyncImageView *_instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}
- (instancetype)init
{
self = [super init];
if (self) {
self.cache = [[NSCache alloc] init];
}
return self;
}
- (void)loadImageView:(UIImageView*)imageView withURLString:(NSString *)urlString
{
UIActivityIndicatorView* activityView;
activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityView.hidesWhenStopped = YES;
activityView.center = CGPointMake(imageView.bounds.size.width / 2.0f, imageView.bounds.size.height / 2.0f);
activityView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
[imageView addSubview:activityView];
[activityView startAnimating];
UIImage* imageLoad = [self.cache objectForKey:urlString];
if (nil != imageLoad) {
imageView.image = imageLoad;
[activityView removeFromSuperview];
}
else {
// Block variable to be assigned in block.
__block NSData *imageData;
// Dispatch a background thread for download
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
UIImage* imageLoad = [[UIImage alloc] initWithData:imageData];
// Update UI on main thread
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self.cache setObject:imageLoad forKey:urlString];
imageView.image = imageLoad;
[activityView removeFromSuperview];
});
});
}
}
//////////////////////////////////////
ViewController.m
//////////////////////////////////////
- (void)viewDidLoad {
[super viewDidLoad];
[[IDAsyncImageView instance] loadImageView:myImageView withURLString:aUrl];
}
Take a look at this control: https://github.com/nicklockwood/AsyncImageView
It's very easy to implement (only 1 header file) and will suit your needs just fine.
Using this control: Instead of declaring:
NSURL *imageURL = ......;
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *imageLoad;
imageLoad = [[UIImage alloc] initWithData:imageData];
imageView.image = imageLoad;
Use:
NSURL *imageURL = ......;
imageView.imageURL = imageURL;
Try this code:
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(q, ^{
/* Fetch the image from the server... */
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
/* This is the main thread again, where we set the tableView's image to
be what we just fetched. */
cell.imgview.image = img;
});
});