wufoo
wufoo

Reputation: 14571

working with variables from dispatch_async

I have a method which downloads some pics from a server. I had the buffer for the downloaded data defined withing async block (NSMutableArray *imgtmp) but haven't figured out how to get the array back out of there. What's the best way to access imgtmp in order to return it's contents, or set an instance variable from it?

I've been looking in the Apple Block docs but I must not be in the right section. Do I need to declare imgtmp using the __block keyword somehow? I tried that but imgtmp was still empty outside the block. Thanks!

EDIT: code updated with working model

- (void) loadImages
{
   // temp array for downloaded images. If all downloads complete, load into the actual image data array for tablerows
   __block NSMutableArray *imgtmp = [[NSMutableArray alloc] init];

   dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0),
   ^{
      int error = 0;
      int totalitems = 0;
      NSMutableArray *picbuf = [[NSMutableArray alloc] init];

      for (int i=0; i < _imageURLS.count;i++)
      {
         NSLog(@"loading image for main image holder at index %i",i);
         NSURL *mynsurl = [[NSURL alloc] initWithString:[_imageURLS objectAtIndex:i]];
         NSData *imgData = [NSData dataWithContentsOfURL:mynsurl];
         UIImage *img = [UIImage imageWithData:imgData];


         if (img)
         {
            [picbuf addObject:img];
            totalitems++;
         }
         else
         {
            NSLog(@"error loading img from %@", [_imageURLS objectAtIndex:i]);
            error++;
         }
      }// for int i...


      dispatch_async(dispatch_get_main_queue(),
      ^{
         NSLog(@"_loadedImages download COMPLETE");
         imgtmp = picbuf;
         [_tvStatus setText: [NSString stringWithFormat:@"%d objects have been retrieved", totalitems]];
         NSLog (@"imgtmp contains %u images", [imgtmp count]);
      });// get_main_queue


   });// get_global_queue


}

Upvotes: 0

Views: 1019

Answers (1)

Aaron Golden
Aaron Golden

Reputation: 7102

You're hitting that "final" NSLog call before any of your block code has executed. All your image loading stuff is wrapped in a dispatch_async. It is executed asynchronously whereas the NSLog is called right away.

I think the best thing for you to do is to pass imgtmp along to some persistent object. Perhaps your view controller can have a property like:

@property (nonatomic, copy) NSArray *images;

and you can assign that in the same block where you assign the text to _tvStatus.

Upvotes: 1

Related Questions