IOS multithreaded Development Operationqueue (ii) nsoperation VS GCD

Source: Internet
Author: User

Original blog, reproduced please indicate the source
Blog.csdn.net/hello_hwc

Welcome to my iOS SDK detailed column
Http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html

Foreword: A bit busy recently, so the number of blogs updated this month has dropped somewhat, estimated that this month and next month the number of blog update is about 10 articles. Back to the point, this article will compare the GCD and nsoperation two kinds of multi-threaded implementation methods. Then explain how to choose, as well as a simple example.

Choose GCD or Nsoperationqueue?

In fact, there is no standard answer, Nsoperationqueue is the upper package of GCD, what is the package? is to pack some functionality together and provide it to the developer. There's a principle in iOS development

The upper-level API is preferred, unless the upper API is not implemented, or if there are performance issues after implementation, the underlying is selected.

In fact, different people have different understandings and habits about this problem. The personal opinion is that the analysis of the nature of their own tasks, in the following cases, priority consideration Nsoperationqueue

    • A dependency between tasks
    • Limit the maximum number of tasks that can be performed.
    • The mission could have been canceled.

GCD is preferred in the following cases:

    • Task is a simple block submission
    • Complex block nesting is required between tasks
    • Tasks require very frequent submissions. (Simply mention this, because Nsoperation is an object that allocates extra memory and frees up memory if the process is very frequent and CPU loss is huge)
About the simple block

GCD can be conveniently used block, for example

dispatch_async0), ^(void) {        //后台操作        dispatch_async(dispatch_get_main_queue(), ^(void) {            //主线程更新UI        });    });

Here, you can copy this code for Sanipet, which makes it easy to use.

dispatch_async(dispatch_get_global_queue(<#dispatch_queue_priority_t priority#>, <#unsigned long flags#>), ^(void) {    <#code#>    dispatch_async(dispatch_get_main_queue(), ^(void) {        <#code#>    });})

Then set the parameters

The personal habit here is that snipet use the name prefix _quick, which can be done according to personal habits.

Of course, Nsoperation also support the submission of block, but it is not gcd convenient to use

queue = [[NSOperationQueue alloc] init];    [queue addOperationWithBlock:^{       //后台操作        [[NSOperationQueue mainQueue] addOperationWithBlock:^{            //主线程更新UI        }];    }];

Here, why is inconvenient, because Nsoperationqueue is an object, the object you have to consider its life cycle (when created, when released), it is obviously not gcd handy more.

There is a dependency between tasks

This is one of the most frequently used topics I've been recruiting recently:

There are three tasks, task one and task two can be carried out at the same time, task three must be done after task one and task two are completed before it can be executed. Finally, all three tasks are completed to inform the user.

See how it's achieved with Nsoperationqueue

Nsoperationqueue * queue = [[Nsoperationqueue alloc] init]; Nsblockoperation * Task1 = [nsblockoperation blockoperationwithblock:^{sleep (1); NSLog (@"Task1 is done");    }]; Nsblockoperation * Task2 = [nsblockoperation blockoperationwithblock:^{sleep (2); NSLog (@"Task2 is done");    }]; Nsblockoperation * Task3 = [nsblockoperation blockoperationwithblock:^{sleep (1); NSLog (@"Task3 is done");    }];    [Task3 Adddependency:task1];    [Task3 Adddependency:task2]; Nsblockoperation * DoneOperation = [Nsblockoperation blockoperationwithblock:^{NSLog (@"All Tasks are done");    }]; [ DoneOperation Adddependency:task1]; [ DoneOperation Adddependency:task2]; [ DoneOperation Adddependency:task3]; [Queue Addoperations:@[task1,task2,task3, DoneOperation] Waituntilfinished:no];

Output

2015-06-2711::. 936 OCTest[1189:72220] Task1  is  Done2015-06-2711::. 938 OCTest[1189:72219] Task2  is  Done2015-06-2711::. 940 OCTest[1189:72219] Task3  is  Done2015-06-2711::. 940 OCTest[1189:72219]  All Task  is  Done

and see how it's implemented with GCD.
Analysis of how to achieve, in fact, and a variety of implementation methods, such as the number of signal control tasks, such as with Dispatchgroup. Here, I choose to use Dispatch_group to achieve

dispatch_group_t group = Dispatch_group_create ();dispatch_queue_tGlobalqueue = Dispatch_get_global_queue (Dispatch_queue_priority_default,0); Dispatch_group_async (Group, Globalqueue, ^{sleep (1);NSLog(@"Task1 is done");    }); Dispatch_group_async (Group, Globalqueue, ^{sleep (2);NSLog(@"Task2 is done");    }); Dispatch_group_notify (Group, Globalqueue, ^{Dispatch_async(Globalqueue, ^{sleep (1);NSLog(@"Task3 is done");Dispatch_async(Dispatch_get_main_queue (), ^{NSLog(@"All Tasks are done");        });    }); });

Output

2015-06-2711:: Approx .. 306 OCTest[1245:76887] Task1  is  Done2015-06-2711:: Panax Notoginseng. 306 OCTest[1245:76886] Task2  is  Done2015-06-2711::. 311 OCTest[1245:76886] Task3  is  Done2015-06-2711::. 312 OCTest[1245:76856]  All Task  is  Done

At first glance, it's good to have a gcd dependency relationship. However, it is important to be clear that GCD does not have a clear dependency, and that the dependency should be implemented by the developer themselves, and when the dependencies are complex, it is easy to make mistakes.

About Complex block nesting

For example, such nesting, GCD is easy to implement, and nsoperation implementation is more complex.

    dispatch_queue_t0);    dispatch_async(globalQueue, ^{        //Do something        dispatch_async(dispatch_get_main_queue(), ^{            //Do something with UI            dispatch_async(globalQueue, ^{                //Do something                dispatch_async(dispatch_get_main_queue(), ^{                    //Do something with UI                });            });        });    });
About task cancellation

GCD there is no obvious task cancellation, you need to implement the task to cancel. For example, keep checking for a bool flag, and if true, return early

Nsoperation can be easily canceled.

Finally, mention the two subcategories of nsoperation

Nsblockoperation
Used to encapsulate a block into a nsoperation.

 NSOperation * blockOperation = [NSBlockOperation blockOperationWithBlock:^{        //Block }];

Nsinvocationoperation
Encapsulates a selector into a nsoperation

NSInvocationOperation * operation = [[NSInvocationOperation alloc] initWithTarget:selfselector:@selector(function) object:nil];-(void)function{    NSLog(@"function");}

Copyright NOTICE: This article is for bloggers original article, if you need to reprint please indicate the source

IOS multithreaded Development Operationqueue (ii) nsoperation VS GCD

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.