IOS Development-Multi-threaded

Source: Internet
Author: User
Tags gcd

The front in the "Bison Eye of the iOS development multithreading is this (ii)" In the article finished multi-threaded NSThread , it is not difficult to find this way of multi-threaded implementation is very complex, in order to simplify the development of multithreading, iOS provides GCD to achieve multithreading. GCD has two core concepts:

Queue: The queue is responsible for managing the tasks submitted by the developer, and the GCD queue always handles the tasks in a first-in, out-of-order manner, but because the tasks do not execute the same time, the tasks that are processed first do not necessarily end first. The queue is either a serial queue or a concurrent queue, and the serial queue processes only one task at a time, the next task must be completed before it is executed, and the queue can handle multiple tasks simultaneously, so there will be multiple tasks executing concurrently. The bottom of the queue maintains a thread pool to handle user-submitted tasks, and the thread pool functions as a task of performing queue management. The thread pool at the bottom of the serial queue simply maintains one thread, and the concurrent queue wants to reverse.

Task: The task is the unit of work that the user submits to the queue, which is committed to the thread pool of the underlying maintenance of the queue, so these tasks are performed in a multithreaded manner.

In summary, it is not difficult to find that the use of GCD only two steps.

1. Create a queue.
2. Submit the task to the queue.

Next I let us play in detail to play this gcd??

First, we'll create the queue.

Gets the queue (obsolete) in which the current execution code is located dispatch_get_current_queue (void);/* To get the global concurrency queue for the system based on the priority and additional flags, the first parameter specifies the priority of the DISPATCH queue, which can be dispatch_queue_priority_hight, dispatch_queue_ Priority_default, Dispatch_queue_priority_low, or Dispatch_queue_priority_background (added by IOS 5.0); The second parameter, currently available only for 0 or Null*/dispatch_get_global_queue (long identifier, unsigned long flags);  Gets the main line threads associated serial queue dispatch_get_main_queue (void)/* Creates a queue from the specified string label. The second parameter controls whether a serial or concurrent queue is created, and if the second parameter is set to "Dispatch_queue_serial", the serial is set to "Dispatch_queue_concurrent" as a concurrent queue. In the absence of an arc mechanism, the usual way to create a queue is to call Dispatch_release () to release the reference count */dispatch_queue_create (const Char *label,  dispatch_queue_attr_t attr); //Gets the string label for the specified queue, dispatch_queue_t represents a queue Dispatch_queue_get_label (dispatch_queue_t queue );   

Depending on the method above, you can create several queues like

1. Get the system default global concurrency queue

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

2. Get the serial queue associated with the main thread of the system

dispatch_queue_t queue = dispatch_get_main_queue();

3. Create a serial queue

dispatch_queue_t queue = dispatch_queue_create("Bison", DISPATCH_QUEUE_SERIAL);

4. Create a concurrent queue

dispatch_queue_t queue = dispatch_queue_create("Bison", DISPATCH_QUEUE_CONCURRENT);
Asynchronous Submit Task

iOS provides the following functions to submit tasks to a queue. Many of these functions have two versions: a receive code block as a version of the parameter, a receive function as the version of the parameter, where the function name of the receiving function has a maximum of _f suffixes, and one more parameter, which is used to pass the application-defined context to the function.

The code block is committed asynchronously to the specified queue, and the underlying thread pool of the queue is responsible for executing the code block Dispatch_async (dispatch_queue_tQueuedispatch_block_t block);The function is committed asynchronously to the specified queue, and the underlying thread pool of the queue is responsible for executing the function dispatch_async_f (dispatch_queue_tQueuevoid *context,dispatch_function_t work);The code block is committed synchronously to the specified queue, and the underlying thread pool of the queue is responsible for executing the code block Dispatch_sync (dispatch_queue_tQueuedispatch_block_t block);The function is committed synchronously to the specified queue, and the underlying thread pool of the queue is responsible for executing the function dispatch_sync_f (dispatch_queue_tQueuevoid *context,dispatch_function_t work);Commits a block of code to the specified queue asynchronously, and the underlying thread pool of the queue is responsible for executing the code block at the time specified by when Dispatch_after (dispatch_time_t when,dispatch_queue_tQueuedispatch_block_t block);Asynchronously submits the function to the specified queue, and the underlying thread pool of the queue is responsible for executing the function at the point specified at the time Dispatch_after_f (dispatch_time_t when,dispatch_queue_tQueuevoid *context,dispatch_function_t work);Commits a block of code asynchronously to the specified queue, and the underlying thread pool of the queue repeats the code block multiple times dispatch_apply (size_t iterations, dispatch_queue_t queue,Void (^block) (size_t));  Asynchronously submits the function to the specified queue, and the underlying thread pool of the queue repeats the function multiple times dispatch_apply_f (size_t iterations, dispatch_queue_t queue,  void *context,void (*work) (void *, size_t));  Submits a code block to the specified queue, which controls the thread pool at the bottom of the queue to execute only once during the lifetime of the app. predicate is a pointer to the dispatch_once_t variable, judging whether it has been executed, the runtime is very common dispatch_once (dispatch_once_t *predicate,  dispatch_block_t block);               

Here are a few simple cases

Define 2 queuesdispatch_queue_t Serialqueue;dispatch_queue_t concurrentqueue;-(void) viewdidload{[Super Viewdidload];Create serial Queue Serialqueue = Dispatch_queue_create ("Fkjava.queue", dispatch_queue_serial);Create a concurrent queue Concurrentqueue = Dispatch_queue_create ("Fkjava.queue", dispatch_queue_concurrent);} - (ibaction) Serial: (ID) sender{Submit 2 blocks of code to the serial queue in turnYou must wait until the 1th block of code is complete before you can execute the 2nd block of code.Dispatch_async (Serialqueue, ^ (void) {for (int i =0; I <100; i + +) {NSLog (@ "%@=== ...-...... ==%d", [Nsthread CurrentThread], i); } });Dispatch_async (Serialqueue, ^ (void) {for (int i =0; I <100; i + +) {NSLog (@ "%@------%d", [Nsthread CurrentThread], i); } });} - (ibaction) Concurrent: (ID) sender{//sequentially submits 2 code blocks to the concurrent queue //two blocks of code can be executed concurrently dispatch_async (concurrentqueue, ^ (void) {for (int i = 0; i <  100; i + +) {nslog (@ "%@=== ...-...... ==%d", [ nsthread CurrentThread], i); } }); dispatch_async (concurrentqueue, ^ (void) {for (int i = 0; i <  100; i + +) {nslog (@ "%@------%d", [ Nsthread CurrentThread], i); } });} 

Compile execution It is not difficult to see that the first is a serial queue and the second is a parallel queue.

Below we will simply cite an example of an asynchronous download image

The code is as follows:

To submit a block of code to the system's global concurrency queueDispatch_async (Dispatch_get_global_queue (Dispatch_queue_priority_high,0), ^ (void) {nsstring* URL =@ "Http://allluckly.cn/images/blog/applepay/6.png";//get data from the network nsdata *data = [[nsurl Urlwithstring:url]]; //Initialize network data to UIImage object uiimage *image = [[uiimage Alloc]initwithdata:data]; if (image = nil) {// The code block is submitted to the main thread associated queue, which will be completed by the main thread dispatch_async (Dispatch_get_main_queue (), ^{self.iv.image = Image;}); //①} else {nslog (@ "---download picture error---") ; }}); 


Here the value of attention is that our image is HTTP, xcode7 above must be set under Info.plist file settings under the network, otherwise it will not succeed!
It is not difficult to see above to send the above example by creating a global concurrency queue, the code block is responsible for downloading pictures from the network, the download is done to the main thread execution.

Synchronizing Submit Tasks

The Dispatch_async () function submits a block of code synchronously, and the function must wait until the end of the code block execution to return. If a program uses this function to commit two blocks of code (concurrent queues), it must wait until the first task finishes executing the second task. As follows??

- (ibaction) Clicked: (ID) sender{Submit 2 blocks of code in a synchronized mannerDispatch_sync (Dispatch_get_global_queue (Dispatch_queue_priority_default,0), ^ (void) {for (int i =0; I <100; i + +) {NSLog (@ "%@=====%d", [nsthread CurrentThread], i); [nsthread sleepfortimeinterval:0.1];}}); //must wait until the first commit code block execution completes, the Dispatch_sync () function will return, //program will not be executed here, To commit the second block of code. dispatch_sync (Dispatch_get_global_queue (Dispatch_queue_priority_default, 0), ^ (void) {for ( int i = 0; i < 100; i + +) {nslog (@ "%@-----%d", [nsthread CurrentThread], i); [nsthread sleepfortimeinterval:0.1];});}    
Perform Tasks multiple times

The dispatch_apply () function repeats code blocks multiple times, and if the code block is submitted to a concurrent queue, the system can execute the same block of code concurrently with multiple threads. Let's take a quick look at??.

- (IBAction)clicked:(id)sender{    // 控制代码块执行5次    dispatch_apply(5    , dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) // time形参代表当前正在执行第几次 , ^(size_t time) { NSLog(@"===执行【%lu】次===%@" , time, [NSThread currentThread]); });}
Perform only one task at a time

Dispatch_once () submits a block of code to the specified queue, which controls the thread pool at the bottom of the queue to execute only once during a life cycle of the application. predicate is a pointer to the dispatch_once_t variable, and it is often used in runtime to determine whether it has been executed. The system executes the code block submitted by the function directly with the main thread. Let's take a quick look at??.

- (IBAction)clicked:(id)sender{        static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{ NSLog(@"==执行代码块=="); // 线程暂停3秒 [NSThread sleepForTimeInterval:3]; });}

Wen/bison (author of Jane's book)
Original link: http://www.jianshu.com/p/2f18ffcd4c22
Copyright belongs to the author, please contact the author to obtain authorization, and Mark "book author".

IOS Development-Multi-threaded

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.