In my app, I load image from the URL:
-(void)loadImages
{
...
image1 = [UIImage imageWithData:[NSData dataWithContentsOfURL:imgUrl1]];
}
In order to avoid blocking the main thread until the download has completed I call this method in -viewDidAppear using GCD
:
dispatch_async( dispatch_get_global_queue(0,0), ^{
[self loadImages];
});
However, when I open my view controller
with the imageView
at the first time, the imageView
is empty (even if I wait for a long time) but after I open this view controller
again and image appears and everything is good to go.
Where is my mistake ? Sorry, new to multithreading :)
EDIT : I also forgot to mention, that I use the image in the tableView
when I get it:
cell.imageView.image = image1;
UIElements in iOS should always be updated via main thread. What you could do is:-
__block NSData *data;
dispatch_queue_t myQueue = dispatch_queue_create("com.appName", NULL);
dispatch_async(myQueue, ^{
data = [NSData dataWithContentsOfURL:imgUrl1];
dispatch_async(dispatch_get_main_queue(), ^(void) {
cell.imageView.image = [UIImage imageWithData = data];
});
});
or Else you there is a better way of fetching images from URL by using AFNetworking. It is faster and easier. You just have to write one line of code:-
[cell.imageView setImageWithURL:imgUrl1];
This may not be the answer that you were looking for, but that's not the recommended way to load URLs. You should use the URL loading classes available such as NSURLRequest and NSURLConnection.
Try this:
NSURLRequest *imageRequest = [[NSURLRequest alloc] initWithURL:imageURL];
[NSURLConnection sendAsynchronousRequest:imageRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
UIImage *image = [[UIImage alloc] initWithData:data];
[imageView setImage:image];
}
}];
You need to inform the view that the image needs to be redrawn. Add:
[imageView setNeedsDisplay];
to the end of your loadImages
method.
You have many problems here:
[NSData dataWithContentsOfURL:imgUrl1]
is not a safe way to load an external resource, even on a different thread (but especially on the main thread). What you should be doing:
You can solve the first three problems by using AFNetworking . It wraps the delegate methods and lets you just provide a success and failure block. AFNetworking's AFImageRequestOperation in particular bounces code between queues as I've described. (It even runs its main networking loop in a different thread, which isn't necessary but since it does it well, why not?)
You'll still need to verify the cell's identity.
Since you are using it in TableView, add [self.tableView reloadData]; in the end of loadImages method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.