How to create an array of UIImages

前端 未结 2 1482
小鲜肉
小鲜肉 2021-01-23 08:26

I\'m storing an image from a Parse database like this:

PFFile *firstImageFile = self.product[@\"firstThumbnailFile\"];
[firstImageFile getDataInBackgroundWithBlo         


        
相关标签:
2条回答
  • 2021-01-23 09:23

    This is form of a common problem: how to do many asynch operations (without deeply nesting completion blocks) and know when they complete. The approach I use is to think of the parameters to the operations as a todo list, and build a method that handles the list recursively....

    - (void)loadPFFiles:(NSArray *)array filling:(NSMutableDictonary *)results completion:(void (^)(BOOL))completion {
        NSInteger count = array.count;
        // degenerate case is an empty array which means we're done
        if (!count) return completion(YES);
    
        // otherwise, do the first operation on the to do list, then do the remainder
        PFFile *file = array[0];
        NSArray *remainder = [array subarrayWithRange:NSMakeRange(0, count-1)];
    
        [file getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
            if (!error) {
                UIImage *image = [UIImage imageWithData:imageData];
                results[file.name] = image;
                [self loadPFFiles:remainder filling:results completion:completion];
            } else {
                completion(NO);
            }
        }];
    }
    

    Call it like this (guessing about your model a little bit):

    NSArray *pfFiles = @[ self.product[@"firstThumbnailFile"], self.product[@"secondThumbnailFile"] ];
    NSMutableDictionary *result = [@{} mutableCopy];
    
    [self loadPFFiles:pfFiles filling:result completion:^(BOOL success) {
        if (success) {
            // result will be an dictionary of the loaded images
            // indexed by the file names
        }
    }];
    
    0 讨论(0)
  • 2021-01-23 09:30

    I would guess (based on your comments about nil above) that your code looks a little like this:

    PFFile *firstImageFile = self.product[@"firstThumbnailFile"];
    [firstImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
        if (!error) {
            self.firstImage = [UIImage imageWithData:imageData];
        }
    }];
    
    self.galleryImages = [NSArray arrayWithObjects: self.firstImage, self.secondImage, nil];
    

    If this is the case, move the array initialization inside the completion block like so:

    PFFile *firstImageFile = self.product[@"firstThumbnailFile"];
    [firstImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
        if (!error) {
            self.firstImage = [UIImage imageWithData:imageData];
    
            dispatch_async(dispatch_get_main_queue(), ^{
    
                    self.galleryImages = [NSArray arrayWithObjects: self.firstImage, self.secondImage, nil];
                });
        }
    }];
    

    What happens in the first (your) case is that the array initialization statement runs before the completion block, so when 'first image' is actually set it is too late as the array has already been initialized.

    0 讨论(0)
提交回复
热议问题