Weakman10122 Weakman10122 - 16 days ago 6
iOS Question

Objective C: For loop is finished before image is finished

I have an

arrayOfLinks
that contains a lot of url links. I need to get images from these links. I am using the following code to do so.

- (void)getImages {
NSArray *links = arrayOfLinks;

for (NSString *link in links ) {
[self.picImage sd_setImageWithURL:[NSURL URLWithString:link] placeholderImage:nil options:SDWebImageHighPriority completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
NSLog(@"pic image set finished");
}];
}
[self finishSettingImages];
NSLog(@"for loop finished");
}


This almost works, but the problem is the for loop finishes before the images are set. I want to call the method
finishSettingImages
after each image is set. What would be the best way to do this?

Edit: I want the method 'finishSettingImages' called after ALL the images are set. Sorry for not clarifying this.

Answer

Just use GCD groups.

    NSArray *links = arrayOfLinks;

    dispatch_group_t group = dispatch_group_create();

    for (NSString *link in links) {

        dispatch_group_enter(group);

        [self.picImage sd_setImageWithURL:[NSURL URLWithString:link] placeholderImage:nil options:SDWebImageHighPriority completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
            dispatch_group_leave(group);
        }];
    }

    // you can use dispatch_get_main_queue() or background here
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        // all is done            
    });

If you only need to get images, you can use SDWebImageManager:

    NSArray *links = arrayOfLinks;

    __block NSMutableArray *images = [NSMutableArray new];

    dispatch_group_t group = dispatch_group_create();

    for (NSString *link in links) {

        dispatch_group_enter(group);
        SDWebImageManager *manager = [SDWebImageManager sharedManager];

        [manager downloadImageWithURL:[NSURL URLWithString:link]
                              options:SDWebImageRetryFailed
                             progress:^(NSInteger receivedSize, NSInteger expectedSize) {}
                            completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
                                if (image) {
                                   [images addObject:image];
                                } 
                                dispatch_group_leave(group);
                            }];

    }

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        // all is done
        for (UIImage *image in images) {
            //do something with images
        }
    });