How to tell if blocks in loop all have completed executing?

前端 未结 4 1941
一个人的身影
一个人的身影 2020-12-02 19:10

I have a loop set up that downloads a series a images which I will later use for to animate using the animationImages property of UIImageView. I wo

4条回答
  •  执念已碎
    2020-12-02 20:00

    Count how many you've completed. The challenging part is making it thread safe. I recommend creating an atomic counter class for that.

    Generic solution!

    + (void)runBlocksInParallel:(NSArray *)blocks completion:(CompletionBlock)completion {
        AtomicCounter *completionCounter = [[AtomicCounter alloc] initWithValue:blocks.count];
        for (AsyncBlock block in blocks) {
            block(^{
                if ([completionCounter decrementAndGet] == 0) {
                    if (completion) completion();
                }
            });
        }
        if (blocks.count == 0) {
            if (completion) completion();
        }
    }
    

    NSMutableArray *asyncBlocks = [NSMutableArray array];
    for (PFObject *pictureObject in objects){
        [asyncBlocks addObject:^(CompletionBlock completion) {
            PFFile *imageFile = [pictureObject objectForKey:@"image"];
            NSURL *imageFileURL = [[NSURL alloc] initWithString:imageFile.url];
            NSURLRequest *imageRequest = [NSURLRequest requestWithURL:imageFileURL];
    
            [tokenImageView setImageWithURLRequest:imageRequest placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
               [self.downloadedUIImages addObject:image]; //This is a mutableArray that will later be set to an UIImageView's animnationImages
            } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
                NSLog(@"Error %@", error);
            } completion:completion];
        }];
    }
    [BlockRunner runBlocksInParallel:[asyncBlocks copy] completion:^{
        //Do your final completion here!
    }];
    

提交回复
热议问题