I am attempting to load 3 images using the method below. The problem is this, I recieve no errors from my completion block and all 3 images only show after I close my detailedViewController and reopen it.
What am I missing ? Thanks for any help, greatly appreciated.
- (UIImage*)loadImageFav1:(NSString *)nameEmail
{
UIImageView *img =[[UIImageView alloc]init];
// NSString *strBack = [NSString stringWithFormat:@"%@%@%@", self.urlPrefix,[self.selectedProfile objectForKey:nameEmailPro],@"_B.png"];
NSString *strProfi = [NSString stringWithFormat:@"%@%@%@", self.urlPrefix,nameEmail,@"_fav1.png"];
//
// NSURL *bkgUrl = [NSURL URLWithString:[strBack stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURL *f1Url = [NSURL URLWithString:[strProfi stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
// // set imges below
NSLog(@"selected fprofile ......str data...%@",strProfi);
////////strt
weakImageViewF1= self.friendImageView1;
[img sd_setImageWithURL:f1Url
placeholderImage:[UIImage imageNamed:@"profile-1.jpg"]
options:SDWebImageRetryFailed
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
NSLog(@"error...back..log %@", error);
if (image) {
// Update model to say that the image was downloaded
NSLog(@"Complete...Background...SSSSSS");
weakImageViewF1.image = image;
[weakImageViewF1 setNeedsLayout];
}
}];
//////
// Test simple call
// [img sd_setImageWithURL:f1Url placeholderImage:[UIImage imageNamed:@"profile-1.jpg"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
// if(error){
// NSLog(@"Callback Error:%@",error);
// }
// if(image){
// NSLog(@"Callback Image:%@",image);
// }
// }];
return img.image;
}
call all 3 images in ViewDidAppear
if ([self loadImageFav1:self.emailID] != nil) {
// call the same method on a background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *tmpF1 = [self loadImageFav1:self.emailID];
UIImage *tmpF2 = [self loadImageFav2:self.emailID];
UIImage *tmpF3 = [self loadImageFav3:self.emailID];
// update UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
self.friendImageView1.image = tmpF1;
self.friendImageView2.image = tmpF2;
self.friendImageView3.image = tmpF3;
});
});
}
///// GOT IT WORKING BUT WOULD LOVE AN EXPLICATION - THANKS
So to get it working I set the sdWebImageWithURL to my original ImageView directly and stopped using the temp UIImageView *img = [[UIimageVew alloc]init];
I went from:
[img sd_setImageWithURL:f1Url placeholderImage:[UIIm...
To:
[self.friendImageView1 sd_setImageWithURL:f1Url placeholderImage:[UIIm...
It is a concurrency problem. SDWebImage is already asynchronous so you're screwing it up by doing your own manual asynchronous thread.
Here is what you're saying:
dispatch_get_main_queue section runs, but Thread B is still in the process of downloading those images so they aren't available yet.The reason they show up next time is because SDWebImage has already cached them from the first attempt.
To fix this problem you should move the code that runs in the dispatch_get_main_queue section into the completed block for the SDWebImage call.
EDIT:
The reason that your change fixed it is because SDWebImage takes care of loading the UIImage into the UIImageView that you gave it in the first place. So you were originally saying "load this image into my UIImageView named img and also assign that image to my other UIImageView named self.friendImageView1", but at the point in time the current image assigned to img was the placeholder image, since the one from the internet had not yet downloaded. Like I said, SDWebImage is doing the download for you automatically in a background thread, and when the download is done it is assigning the downloaded image to that UIImageView that you were calling it on. So basically your original code just added an extra middleman.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With