3 ways to implement IOS multithreaded programming _ios

Source: Internet
Author: User
Tags gcd

Objective

In the multithreaded introduction, I've already explained that in order to improve the smoothness of the interface and the user experience. It is important that you do not block the main thread by putting time-consuming operations into other threads.
There are 3 kinds of multithreaded programming methods in iOS:

Nsthread Grand
centeral Dispatch (GCD)
nsoperation and Nsoperationqueue

1.NSThread

This is the most lightweight multithreaded approach, using the most intuitive multithreaded programming method. But because you need to manage the lifecycle of the thread yourself, thread synchronization. Nsthread is often used for debugging and is not recommended in actual projects.

Gets the current thread
nsthread *current = [Nsthread CurrentThread];
Gets the main thread
nsthread *main = [Nsthread mainthread];

NSLog (@ "Thread---%@", current);
NSLog (@ "Main thread---%@", main);

Console output Results:

2015-11-22 22:30:29.572 multi-threaded demo[1289:2925847] current thread---<nsthread:0x7fc0e1401dc0>{number = 1, name = main}
2015-11-22 22:30:29.572 multi-threaded demo[1289:2925847] Main thread---<nsthread:0x7fc0e1401dc0>{number = 1, name = main}
from the result we see that the current thread is the main one, number is the thread's id,name, and the number of the main thread is 1.

Blocking Threads:

Blocking threads for 3 seconds
[Nsthread Sleepfortimeinterval:3];
[Nsthread sleepuntildate:[nsdate Datewithtimeintervalsincenow:3]];

2.GCD (Grand-Dispatch)

GCD is based on the C language API implementation of a set of multithreaded concurrency mechanism, very flexible and convenient, in the actual development of the use of a wide range.
Simply put, the CGD is to put the operation in the queue to execute.
All you have to do is define the operations and queues, and you don't need to directly control the thread's creation and destruction, and the thread's lifecycle is managed by the queue.

Queue: Responsible for the operation of the scheduling and implementation, with advanced first out (FIFO) characteristics. This means that the queue is first executed first, followed by the subsequent execution of the join.

There are two types of queues:

Serial queues:

The actions in the queue are executed sequentially, and you can imagine queues in a single window.


Parallel queues:

The actions in the queue may be executed concurrently, depending on the type of operation you can imagine as multiple window queues.

Copy Code code as follows:
To create a serial queue
dispatch_queue_t q = dispatch_queue_create ("My_serial_queue", dispatch_queue_serial);
Create a parallel queue
dispatch_queue_t q = dispatch_queue_create ("My_concurrent_queue", dispatch_queue_concurrent);

My_serial_queue and My_concurrent_queue are the name tags of the queues, in order to differentiate with other queues, which must be unique within a project.
Dispatch_queue_serial represents a serial queue
Dispatch_queue_concurrent represents a parallel queue

There are also two types of operations:
Sync operation: Will only execute sequentially, the order of execution is OK.
Asynchronous operations: Order determination in serial queues, execution order indeterminate in parallel queues

Use block to define the code to be executed by the operation, Q is already defined, the queue to join

Define sync operation
Dispatch_sync (q, ^{
  //code to execute  
);
Define asynchronous Operation
Dispatch_async (q, ^{
  //code to execute   
);

Let's take a look at synchronization, asynchronous operations are added to the serial and parallel queues, the sequence and characteristics of execution:
1. Synchronization operations, regardless of the queue to which they are added, are performed sequentially in the main thread

dispatch_queue_t q_serial = dispatch_queue_create ("My_serial_queue", dispatch_queue_serial);
dispatch_queue_t q_concurrent = dispatch_queue_create ("My_concurrent_queue", dispatch_queue_concurrent);
for (int i = 0; i < 5 ++i) {
  dispatch_sync (q_serial, ^{
    NSLog (@ "Sync task in serial queue%@%d", [Nsthread CurrentThread], I );
  });
}
for (int i = 0; i < 5 ++i) {
  dispatch_sync (q_concurrent, ^{
    NSLog (@ "Sync task in parallel queue%@%d", [Nsthread CurrentThread ], I ();
  });

Here is the console output result:

2015-11-23 00:40:36.862 01.GCD Walkthrough [1952:3,613,752] synchronization task in serial queue <nsthread:0x7ff833505450>{number = 1, name = main} 0
2015-11-23 00:40:36.863 01.GCD Walkthrough [1952:3,613,752] synchronization task in serial queue <nsthread:0x7ff833505450>{number = 1, name = main} 1
2015-11-23 00:40:36.863 01.GCD Walkthrough [1952:3,613,752] synchronization task in serial queue <nsthread:0x7ff833505450>{number = 1, name = main} 2
2015-11-23 00:40:36.863 01.GCD Walkthrough [1952:3,613,752] synchronization task in serial queue <nsthread:0x7ff833505450>{number = 1, name = main} 3
2015-11-23 00:40:36.863 01.GCD Walkthrough [1952:3,613,752] synchronization task in serial queue <nsthread:0x7ff833505450>{number = 1, name = main} 4
2015-11-23 00:40:36.863 01.GCD Walkthrough [1952:3,613,752] synchronization task in parallel queue <nsthread:0x7ff833505450>{number = 1, name = main} 0
2015-11-23 00:40:36.863 01.GCD Walkthrough [1952:3,613,752] synchronization task in parallel queue <nsthread:0x7ff833505450>{number = 1, name = main} 1
2015-11-23 00:40:36.863 01.GCD Walkthrough [1952:3,613,752] synchronization task in parallel queue <nsthread:0x7ff833505450>{number = 1, name = main} 2
2015-11-23 00:40:36.864 01.GCD Walkthrough [1952:3,613,752] synchronization task in parallel queue <nsthread:0x7ff833505450>{number = 1, name = main} 3
2015-11-23 00:40:36.864 01.GCD Walkthrough [1952:3,613,752] synchronization task in parallel queue <nsthread:0x7ff833505450>{number = 1, name = main} 4

2. Asynchronous operations are performed only on threads that are not the main thread, and asynchronous operations in the serial queue are executed sequentially in the newly created thread.

Copy Code code as follows:
dispatch_queue_t q_serial = dispatch_queue_create ("My_serial_queue", dispatch_queue_serial);
for (int i = 0; i < 5; ++i) {
Dispatch_async (Q_serial, ^{
NSLog (@ "Serial Queue--asynchronous task%@%d", [Nsthread CurrentThread], i);
});
}

Because it is an asynchronous operation, a new thread is created. Because they are added to the serial queue, all operations are performed sequentially.

2015-11-23 01:03:22.372 01.GCD Walkthrough [2,081:3,627,139] serial Queue--Asynchronous Task <nsthread:0x7fb593d42f50>{number = 2, name = (null)} 0
2015-11-23 01:03:23.373 01.GCD Walkthrough [2,081:3,627,139] serial Queue--Asynchronous Task <nsthread:0x7fb593d42f50>{number = 2, name = (null)} 1
2015-11-23 01:03:24.374 01.GCD Walkthrough [2,081:3,627,139] serial Queue--Asynchronous Task <nsthread:0x7fb593d42f50>{number = 2, name = (null)} 2
2015-11-23 01:03:25.375 01.GCD Walkthrough [2,081:3,627,139] serial Queue--Asynchronous Task <nsthread:0x7fb593d42f50>{number = 2, name = (NULL)} 3
2015-11-23 01:03:26.376 01.GCD Walkthrough [2,081:3,627,139] serial Queue--Asynchronous Task <nsthread:0x7fb593d42f50>{number = 2, name = (NULL)} 4

3. Asynchronous operation, parallel queue

Copy Code code as follows:
dispatch_queue_t q_concurrent = dispatch_queue_create ("My_concurrent_queue", dispatch_queue_concurrent);
for (int i = 0; i < 5; ++i) {
Dispatch_async (Q_concurrent, ^{
NSLog (@ "Parallel queue--asynchronous task%@%d", [Nsthread CurrentThread], i);
});
}

Theoretically, the parallel queue creates a new thread for each asynchronous operation and then lets all the tasks execute concurrently. But in fact the number of threads that the system can create is limited, and when the thread that is created reaches the maximum number of threads, subsequent asynchronous operations need to wait for the previous operation to complete before they are executed. Which thread operation completes, arranges the waiting asynchronous task to which thread. Until all operations have been completed.
You can observe this phenomenon by changing the number of loops in the above code to 5000.
2015-11-23 01:14:15.282 01.GCD Walkthrough [2,165:3,634,728] parallel Queue--Asynchronous Task <nsthread:0x7fb3b841b0a0>{number = 4, name = (NULL) } 3
2015-11-23 01:14:15.282 01.GCD Walkthrough [2,165:3,634,724] parallel Queue--Asynchronous Task <nsthread:0x7fb3b8514da0>{number = 3, name = (null)} 0
2015-11-23 01:14:15.282 01.GCD Walkthrough [2,165:3,634,726] parallel Queue--Asynchronous Task <nsthread:0x7fb3b8604db0>{number = 5, name = (null)} 2
2015-11-23 01:14:15.282 01.GCD Walkthrough [2,165:3,634,725] parallel Queue--Asynchronous Task <nsthread:0x7fb3b86119d0>{number = 2, name = (null)} 1
2015-11-23 01:14:15.285 01.GCD Walkthrough [2,165:3,634,729] parallel Queue--Asynchronous Task <nsthread:0x7fb3b87011f0>{number = 6, name = (NULL)} 4

3.NSOperation & Nsoperationqueue

Although GCD is already powerful, the API it uses is still in C language. At some point, it is very inconvenient and unsafe to use in object-oriented objective-c.

So Apple abstracts the operations in GCD into Nsoperation objects, abstracting the queues as Nsoperationqueue objects.


Abstract for the benefit of Nsoperation & Nsoperationqueue after a few:

Code style Unified, we do not have to write in the object-oriented objective-c in the face of the process of the C language code.
We know that the execution code of the operation in GCD is written in the anonymous block, so it is difficult to set dependencies on the operation and cancel the operation. These features are already encapsulated within the Nsoperation object. ^-^
Nsoperationqueue objects are more powerful and flexible than queues in gcd, such as setting the number of concurrent operations and canceling all operations in the queue.
Nsoperation are divided into nsinvocationoperation and nsblockoperation

The use of nsinvocationoperation

First, define a Nsoperationqueue object
nsoperationqueue *queue = [[Nsoperationqueue alloc] init];
Nsinvocationoperation *op = [[Nsinvocationoperation alloc] initwithtarget:self selector: @selector (operationaction:) object:@ "Here can wear parameters"];
[Queue addoperation:op];//the operation into the queue
-(void) Operationaction: (id) obj
{
  NSLog (@ "%@-obj:%@", [ Nsthread CurrentThread], obj);

The output is:

2015-11-23 02:55:19.067 multi-threaded demo[2604:3686934] <nsthread:0x7f9dfa443510>{number = 2, name = (null)}-obj: You can wear parameters here
The use of nsblockoperation

Nsoperationqueue *queue = [[Nsoperationqueue alloc] init];
Nsblockoperation *op = [Nsblockoperation blockoperationwithblock:^{
[Self operationaction:@ "This is Nsblockoperation"];
}];
[Queue Addoperation:op];
The output is:

2015-11-23 02:56:11.812 multi-threaded demo[2617:3687872] <nsthread:0x7fa983f10a50>{number = 2, name = (null)}-obj: This is Nsbloc Koperation
Set dependencies (Order of execution)

Nsoperationqueue *queue = [[Nsoperationqueue alloc] init];
Nsinvocationoperation *OP1 = [[Nsinvocationoperation alloc] initwithtarget:self selector: @selector (operationaction:) object:@ "OP1"];
Nsinvocationoperation *OP2 = [[Nsinvocationoperation alloc] initwithtarget:self selector: @selector (operationaction:) object:@ "OP2"];
OP2 is executed after OP1
[OP2 adddependency:op1];//Here you need to be aware that you must set up dependencies before addoperation

[Queue ADDOPERATION:OP1];
[Queue ADDOPERATION:OP2];
The output is:

2015-11-23 02:57:40.283 multi-threaded demo[2661:3689737] <nsthread:0x7fb663e132d0>{number = 2, name = (null)}-OBJ:OP1
2015-11-23 02:57:40.284 multi-threaded demo[2661:3689737] <nsthread:0x7fb663e132d0>{number = 2, name = (null)}-OBJ:OP2
the output of the dependency is not set:

2015-11-23 03:00:45.939 multi-threaded demo[2709:3692307] <nsthread:0x7fe951d0d8a0>{number = 2, name = (null)}-obj: OP2
2015-11-23 03:00:45.939 multithreading demo[2709:3692308] <nsthread:0x7fe951c24720>{number = 3, name = (null)}-obj: OP1
Here you should find that, in Nsoperation & Nsoperationqueue, we do not need to define the type of operation and the type of queue and control the order of execution of the operation, like GCD. You just need to set the order of execution of the operation directly.

Related Article

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.