3

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...
AhabLives
  • 1,308
  • 6
  • 22
  • 34

1 Answers1

1

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:

  1. In a new background thread (Thread A), start downloading the images.
  2. This new background thread (Thread A) is starting up it's own background thread (Thread B, SDWebImage is doing this for you).
  3. Your background Thread A ends.
  4. The code in your 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.

Mike S
  • 11,329
  • 6
  • 41
  • 76
  • Thanks for the help. I have taken out the background Thread so my viewDidAppear now looks like this.... self.friendImageView1.image = [self loadImageFav1:self.emailID]; self.friendImageView2.image = [self loadImageFav2:self.emailID]; self.friendImageView3.image = [self loadImageFav3:self.emailID];....No Luck I only get placeholder image until I reload the VC. – AhabLives Sep 25 '15 at 18:31
  • Big Thanks @Mike for the explanation. I hate not understanding why something DOES work more than anything. – AhabLives Sep 25 '15 at 20:12