0

I have the following code and it does not work. Is there something working behind it.

[operationQueue addOperationWithBlock:^{
        imageData =  [NSData dataWithContentsOfURL:imageURL];
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            UIImage *image = nil;

            if(imageData){
                UIImage *image = [UIImage imageWithData:imageData];
                cell.imageView.image = image;
            }
        }];
    }];

Even I create a subclass of NSOperation and then alloc init it, it does not work the way I think it to. I always have to invoke start to the NSOperation subclass to run but I suppose sending start message to NSOperation runs it in the main thread rather than running in the background thread.

Sandeep
  • 20,908
  • 7
  • 66
  • 106
  • 3
    What is the output? IF you want help, tell us what error was triggered. We are not mind-readers. – Steven Oct 30 '12 at 15:24
  • Have you tried putting breakpoints at the lines `imageData = [NSData dataWithContentsOfURL:imageURL];` and `UIImage *image = nil;`? Knowing this will allow us to know whether your program is ever executing the blocks which you've added to the two different `NSOperationQueue`s. If you do break at `UIImage *image = nil;`, please print `[imageData length]`. – Nate Chandler Oct 30 '12 at 15:26
  • This does not work with me, I could not load image this way. I have empty response and it seems that the block for downloading the image is not being called at all. – Sandeep Oct 30 '12 at 15:28
  • @koyla If `dataWithContentsOfURL:` returns `nil`, then there is something amiss with your URL. If, on the other hand, after setting your breakpoint, you never break at the line `imageData = [NSData dataWithContentsOfURL:imageURL];`, then there is something wrong with your `operationQueue`. How is it initialized? – Nate Chandler Oct 30 '12 at 15:33
  • I am not really sure the whole context, but it seem you are trying to do a `cell.imageView.image` inside a queue (which runs on another thread). Only the main thread is allowed to make changes to the UI. You may want to call a `@selector` and perform that on the main thread and then set the image – Steven Oct 30 '12 at 15:33
  • FYI, `NSOperationQueue` is not thread safe. Look at this post for explanation on thread safe: http://stackoverflow.com/questions/8597832/thread-safety-nsoperationqueue-array-addobject – Steven Oct 30 '12 at 15:36
  • @Steven he is running that UI operation on [NSOperationQueue mainQueue], so that should be OK. – Graham Perks Oct 30 '12 at 19:54
  • What is 'operationQueue'. Has it been init'd properly - it's not null, right? – Graham Perks Oct 30 '12 at 19:55
  • operationQueue is simple a property which is initialized inside viewDidLoad method as; self.operationQueue = [[NSOperationQueue alloc] init]; And then I keep on adding the operation to this instance, is there something wrong with this approach ? – Sandeep Oct 30 '12 at 20:57
  • operationQueue is simple a property which is initialized inside viewDidLoad method as; self.operationQueue = [[NSOperationQueue alloc] init]; – Sandeep Oct 30 '12 at 20:58

1 Answers1

1

I want to add an alternative solution using GCD :

backgroundQueue = dispatch_queue_create("com.razeware.imagegrabber.bgqueue", NULL);
dispatch_async(backgroundQueue, ^{
                          /* put the codes which makes UI unresponsive like reading from network*/ 
                         imageData =  [NSData dataWithContentsOfURL:imageURL];
                         .....   ;
                         dispatch_async(dispatch_get_main_queue(),^{
                                         /* do the UI related work on main thread */
                                         UIImage *image = [UIImage imageWithData:imageData];
                                         cell.imageView.image = image;
                                         ......;   });
                                  });
dispatch_release(backgroundQueue);

Let me know whether this one helped you ;)

Reference

subhash kumar singh
  • 2,716
  • 8
  • 31
  • 43
  • Hard to decide which implementation looks cleaner. I like both. The downside with this one is the need to remember dispatch_release(). – Graham Perks Oct 30 '12 at 19:57