objective c - Parse PFFile download order iOS -


i'm storing 5 pffiles in array , using getdatainbackgroundwithblock download files parse.

the problem order @ appear in table view cells different every time, presumably because files download @ different speeds due different file sizes.

for (pffile *imagefile in self.imagefiles) {   [imagefile getdatainbackgroundwithblock:^(nsdata *imagedata, nserror *error) {     if (!error) {       uiimage *avatar = [uiimage imagewithdata:imagedata];       [self.avatars addobject:avatar];       cell.userimageview.image = self.avatars[indexpath.row];     }   }]; } 

the self.imagefiles array in correct order. how ensure images downloaded added self.avatars array in same order self.imagefiles?

the question has 2 parts: (1) explicitly, how maintain order of results of asynchronous operations, (2) implied use of cell, how handle asynch requests in support of tableview.

the answer first question simpler: keep result of request associated parameter request.

// change avatars hold dictionaries associating pffiles images @property(nonatomic,strong) nsmutablearray *avatars;   // initialize (pffile *imagefile in self.imagefiles) {     [avatars addobject:[@{@"pffile":imagefile} mutablecopy]]; }  // lets factor avatar fetch own method - (void)avatarforindexpath:(nsindexpath *)indexpath completion:^(uiimage *, nserror *)completion {      // if fetched already, return via completion block     uiimage *existingimage = self.avatars[indexpath.row][@"image"];     if (existingimage) return completion(existingimage, nil);      pffile *pffile = self.avatars[indexpath.row][@"pffile"];     [pffile getdatainbackgroundwithblock:^(nsdata *imagedata, nserror *error) {         if (!error) {             uiimage *avatar = [uiimage imagewithdata:imagedata];             self.avatars[indexpath.row][@"image"] = avatar;             completion(avatar, nil);         } else {             completion(nil, error);         }     }]; } 

okay part (1). part 2, cellforrowatindexpath code must recognize cells reused. time asynch image fetch happens, cell you're working on might have scrolled away. fix not referring cell in completion block (only indexpath).

    // somewhere in cellforrowatindexpath     // we're ready setup cell's image view       uiimage *existingimage = self.avatars[indexpath.row][@"image"];     if (existingimage) {         cell.userimageview.image = existingimage;     } else {         cell.userimageview.image = // can put placeholder image here while fetch         [self avatarforindexpath:indexpath completion:^(uiimage *image, nserror *error) {             // here's trick missed, don't refer cell, instead:             if (!error) {                 [tableview reloadrowsatindexpaths:@[indexpath]];             }         }];     } 

reloading row in completion block cause cellforrowatindexpath called again, except on subsequent call, we'll have existing image , cell configured immediately.


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -