0

Are there any difference when using this(this is the code just for testing purposes):

dispatch_async(dispatch_get_main_queue(), ^{
                [self.progressBar setProgress:progressValue];
});

instead of this:

[[NSOperationQueue mainQueue] addOperationWithBlock:^
{
    [self.progressBar setProgress:progressValue];
}];

I am using the code above in this context:

NSOperationQueue *progressQueue = [[NSOperationQueue alloc] init];


    [progressQueue addOperationWithBlock:^{
        for (int i = 1; i <= 10; i++) {
            sleep(1);
            float progressValue = (float)i/10.0;

            /* GCD
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.progressBar setProgress:progressValue];
            });
            */
            /* Does this have the same effect as using GCD from above
            [[NSOperationQueue mainQueue] addOperationWithBlock:^
             {
                  [self.progressBar setProgress:progressValue];
             }];
             */
        }
    }];
Whirlwind
  • 14,286
  • 11
  • 68
  • 157
  • In your case I would use GCD. NSOperation have some features: they can be cancelled and have dependencies. GCD can be used for working with files and memory blocks. You need make decision by task, that you are trying to solve. – Cy-4AH Mar 30 '15 at 14:26
  • @Cy-4AH thanks for your reply, I'll keep that in mind. Yeah, I am kind of aware that NSOperation offers higher level of abstraction when working with threads and has it's on nice little features (which GCD does not have) like cancelling operations from the queue. But, I was interested are those two examples accomplishing exactly the same task or not? – Whirlwind Mar 30 '15 at 14:41
  • 2
    NSOperation is a cocoa object instead of GCD isn't. Use NSOperation only when you can't do what you want with GCD – Kevin Machado Mar 30 '15 at 15:16
  • @thedjnivek Thanks, I understand what you and Cy-4AH have pointed. Also I was not taking into consideration possible overhead, but rather effects of these two techniques(updating a progress bar)...And that was just for learning purposes to understand NSOperation better.... I'll stick to the GCD as suggested because I think I can do everything ( I am trying to implement custom progress bar in SpriteKit) like that. – Whirlwind Mar 30 '15 at 15:38
  • Actually this is not a duplicate of that question, because my question is based on my particular example and not on GCD vs NSOperation generally... ;) – Whirlwind Mar 30 '15 at 15:43
  • @thedjnivek That's not accurate. Blocks have been Cocoa objects since iOS 6 and OS X 10.8. Explained here: http://stackoverflow.com/questions/8618632/does-arc-support-dispatch-queues – ipmcc Mar 30 '15 at 19:53

2 Answers2

0

These two are effectively the same.

ipmcc
  • 29,581
  • 5
  • 84
  • 147
0

Same thing, but not really ... !

As @BradLarson said here NSOperation vs Grand Central Dispatch

Before GCD, I used a lot of NSOperations / NSOperationQueues within my applications for managing concurrency. However, since I started using GCD on a regular basis, I've almost entirely replaced NSOperations and NSOperationQueues with blocks and dispatch queues. This has come from how I've used both technologies in practice, and from the profiling I've performed on them.

First, there is a nontrivial amount of overhead when using NSOperations and NSOperationQueues. These are Cocoa objects, and they need to be allocated and deallocated. In an iOS application that I wrote which renders a 3-D scene at 60 FPS, I was using NSOperations to encapsulate each rendered frame. When I profiled this, the creation and teardown of these NSOperations was accounting for a significant portion of the CPU cycles in the running application, and was slowing things down. I replaced these with simple blocks and a GCD serial queue, and that overhead disappeared, leading to noticeably better rendering performance. This wasn't the only place where I noticed overhead from using NSOperations, and I've seen this on both Mac and iOS.

Second, there's an elegance to block-based dispatch code that is hard to match when using NSOperations. It's so incredibly convenient to wrap a few lines of code in a block and dispatch it to be performed on a serial or concurrent queue, where creating a custom NSOperation or NSInvocationOperation to do this requires a lot more supporting code. I know that you can use an NSBlockOperation, but you might as well be dispatching something to GCD then. Wrapping this code in blocks inline with related processing in your application leads in my opinion to better code organization than having separate methods or custom NSOperations which encapsulate these tasks.

NSOperations and NSOperationQueues still have very good uses. GCD has no real concept of dependencies, where NSOperationQueues can set up pretty complex dependency graphs. I use NSOperationQueues for this in a handful of cases.

Overall, while I usually advocate for using the highest level of abstraction that accomplishes the task, this is one case where I argue for the lower-level API of GCD. Among the iOS and Mac developers I've talked with about this, the vast majority choose to use GCD over NSOperations unless they are targeting OS versions without support for it (those before iOS 4.0 and Snow Leopard).

Community
  • 1
  • 1
Kevin Machado
  • 4,141
  • 3
  • 29
  • 54
  • This is misleading. There may be *more* overhead involved in NSOperations, but it's not allocation and deallocation. GCD blocks (that get submitted to queues) are also heap-allocated objects, so as far as memory management, there is the very same allocation and deallocation burden. If you prefer working with NSOp, feel free to keep doing so until you profile your app like this guy did and see that it's a problem. – ipmcc Mar 30 '15 at 19:44