Multi-threaded explanation
The previous introduction of the various ways of multithreading and its use, here to complement a bit on the concept of multithreading and related techniques and use, I believe the front does not understand the place to see after you have no problem with multithreading basically!
First of all, the concepts that iOS must understand in developing multiple threads:
Process
- The In-progress program is called a process, which is responsible for the memory allocation that the program runs
- Each process has its own independent virtual memory space
Thread
- A thread is a separate execution path in the process (Control unit)
- At least one thread is included in a process, that is, the main path
- You can place time-consuming execution paths (such as network requests) on other threads
- The purpose of creating a thread is to open a new execution path, run the specified code, and run concurrently with the code implementation in the main thread
Three ways to 2--multi-threading:
Nsthread
- It is very convenient to build a thread using the Nsthread object
- But! It is very difficult to manage multiple threads using Nsthread, it is not recommended to use
- Skills! Use [Nsthread CurrentThread] to track task threads for these three technologies
Nsoperation/nsoperationqueue
- is a set of OBJECTIVE-C APIs implemented using GCD
- is object-oriented threading technology
- Provides some features that are not easily implemented in GCD, such as limiting the maximum number of concurrent numbers, and the dependencies between operations
Gcd--grand Central Dispatch
- is based on the C language underlying API
- Use block to define tasks, which is very flexible and convenient.
- Provides additional control capabilities and underlying functions that are not available in the Operation queue
3--most commonly used in the development of GCD:
The basic idea of GCD is to put the operation s in the queue s to execute
- Operations using blocks definitions
- The queue is responsible for scheduling the thread on which the task executes and the specific execution time
- The queue is characterized by first in, Out (FIFO), and new additions to the column will be queued at the end of the team
Tips
The functions of GCD are all beginning with dispatch (Dispatch, Dispatch).
Queue
dispatch_queue_t
- Serial queue, the tasks in the queue are only executed sequentially
- Parallel queues, tasks in a queue are typically executed concurrently
Operation
- Dispatch_async asynchronous operations, executing concurrently, unable to determine the order in which the tasks are executed
- Dispatch_sync synchronous operations, which are executed sequentially, to determine the order in which the tasks are executed
4--Serial queue:
- dispatch_queue_t q =dispatch_queue_create ("Cn.itcast.demoqueue", dispatch_queue_serial);
- Dispatch_sync (q, ^{
- NSLog (@ "Serial sync%@", [Nsthread CurrentThread]);
- });
- Dispatch_async (q, ^{
- NSLog (@ "Serial async%@", [Nsthread CurrentThread]);
- });
5--Parallel queues:
- dispatch_queue_t q =dispatch_queue_create ("Cn.itcast.demoqueue", dispatch_queue_concurrent);
- Dispatch_sync (q, ^{
- NSLog (@ "Parallel sync%@", [Nsthread CurrentThread]);
- });
- Dispatch_async (q, ^{
- NSLog (@ "Parallel asynchronous%@", [Nsthread CurrentThread]);
- });
6--: Global queue:
- dispatch_queue_t Q =dispatch_get_global_queue (dispatch_queue_priority_default, 0);
- Dispatch_async (q, ^{
- NSLog (@ "Global asynchronous%@%d", [Nsthread CurrentThread], i);
- });
- Dispatch_sync (q, ^{
- NSLog (@ "Global sync%@%d", [Nsthread CurrentThread], i);
- });
7--Home column:
- dispatch_queue_t q = Dispatch_get_main_queue ();
- Dispatch_async (q, ^{
- NSLog (@ "Home row async%@", [Nsthread CurrentThread]);
- });
- Dispatch_sync (q, ^{
- NSLog (@ "Home row sync%@", [Nsthread CurrentThread]);
- });
8--results of nesting dispatch_sync in different queues:
- Global queues, which are executed on the main thread, do not deadlock
- dispatch_queue_t q =dispatch_get_global_queue (dispatch_queue_priority_default,0);
- Parallel queues, which are executed on the main thread, do not deadlock
- dispatch_queue_t q = dispatch_queue_create ("Cn.itcast.gcddemo", dispatch_queue_concurrent);
- Serial queue, deadlock, but the code before the nested synchronization operation is executed
- dispatch_queue_t q = dispatch_queue_create ("Cn.itcast.gcddemo", dispatch_queue_serial);
- Direct deadlock
- dispatch_queue_t q = Dispatch_get_main_queue ();
- Dispatch_sync (q, ^{
- NSLog (@ "Sync task%@", [Nsthread CurrentThread]);
- Dispatch_sync (q, ^{
- NSLog (@ "Sync task%@", [Nsthread CurrentThread]);
- });
- });
9--:dispatch_sync's application Scenario
Block the execution of a parallel queue, requiring that an operation be performed before subsequent operations, such as user logon
Ensure that local variables outside the block code are actually modified
- dispatch_queue_t q = dispatch_queue_create ("Cn.itcast.gcddemo", dispatch_queue_concurrent);
- __block BOOL logon = NO;
- Dispatch_sync (q, ^{
- NSLog (@ "Analog time-consuming Operation%@", [Nsthread CurrentThread]);
- [Nsthread sleepfortimeinterval:2.0f];
- NSLog (@ "Analog time-consuming completion%@", [Nsthread CurrentThread]);
- Logon =yes;
- });
- Dispatch_async (q, ^{
- NSLog (@ "Login completed processing%@", [Nsthread CurrentThread]);
- });
Note:
- Serial queue, synchronous task, no new thread required
- Serial queue, asynchronous task, requires a child thread, thread creation and recycling does not require programmer involvement!
- "Is the safest one to choose" Serial queue can only be created!
- Parallel queue, synchronous task, no need to create thread
- Parallel queue, asynchronous task, how many tasks, open n threads Execute,
No matter what the queue and what tasks, the creation and recycling of threads does not require programmer involvement.
The creation of a thread is handled by the queue
"Concurrent" programming, in order to let programmers from the responsible line program control to free out! Only need to face queues and tasks!
10--GCD Summary:
GCD
- With GCD, developers no longer have to deal directly with threads, simply add code blocks to the queue to
- GCD manages a thread pool at the backend, gcd not only determines which thread the code block will be executed on, but also manages those threads based on available system resources. This frees the developer from the work of thread management, easing the problem of a large number of threads being created through a centralized management thread
- With GCD, developers can think of work as a queue rather than a bunch of threads, a parallel, abstract model that is easier to master and use
Queue of GCD
- GCD exposes 5 different queues: The primary queue running in the main thread, 3 different priority background queues, and a lower priority background queue (for I/O)
- Custom queues: Serial and parallel queues. Custom queues are very powerful and are recommended for use in development. All blocks that are scheduled in the custom queue will eventually be placed in the system's global queue and in the thread pool
- Tip: It is not recommended to use a queue of different priorities, because if poorly designed, a priority reversal may occur, that is, low-priority operations block high-priority operations
11--nsoperationqueue:
Brief introduction
Nsoperationqueue (Operation queue) is a cocoa abstraction of the queue model provided by GCD and is a set of Objective-c APIs
GCD provides a lower level of control, while the operations queue implements some handy features on top of GCD, which are often the best and safest choice for developers
Queues and operations
Nsoperationqueue has two different types of queues: Primary queue and Custom queue
The primary queue runs on the main thread
Custom queues are executed in the background
The task that the queue handles is a subclass of Nsoperation
Nsinvocationoperation
Nsblockoperation
Basic steps:
- Basic use Steps
- Defining an action queue
- Defining actions
- Add an action to a queue
Tip: Once the operation is added to the queue, the operation is immediately scheduled for execution
12--nsinvocationoperation (Dispatch operation):
defining queues
Self.myqueue = [[Nsoperationqueue alloc] init];
Method of Operation Invocation
- -(void) Operationaction: (ID) obj
- {
- NSLog (@ "%@-obj:%@", [Nsthread CurrentThread], obj);
- }
Define actions and add to queues
- Nsinvocationoperation *op = [[nsinvocationoperation alloc]initwithtarget:self selector: @selector (operationaction:) object:@ (i)];
- [Self.myqueue Addoperation:op];
Summary: you need to prepare a scheduled method and be able to receive a parameter
13--nsblockoperation (Block operation):
Define actions and add to queues
- Nsblockoperation *op = [nsblockoperationblockoperationwithblock:^{
- [selfoperationaction:@ "Block operation"];
- }];
Add an action to a queue
[Self.myqueue Addoperation:op];
Summary: Nsblockoperation more flexible than nsinvocationoperation
14--to set the dependencies for an operation:
- Nsblockoperation *OP1 = [nsblockoperationblockoperationwithblock:^{
- NSLog (@ "%@-Download Image", [Nsthread CurrentThread]);
- }];
- Nsblockoperation *OP2 = [nsblockoperationblockoperationwithblock:^{
- NSLog (@ "%@-add image Filter", [Nsthread CurrentThread]);
- }];
- Nsblockoperation *OP3 = [nsblockoperationblockoperationwithblock:^{
- NSLog (@ "%@-Update UI", [Nsthread CurrentThread]);
- }];
- [Op2 ADDDEPENDENCY:OP1];
- [Op3 ADDDEPENDENCY:OP2];
- [Self.myqueue ADDOPERATION:OP1];
- [Self.myqueue ADDOPERATION:OP2];
- [[Nsoperationqueue Mainqueue] addoperation:op3];
tip: You can use Adddependency to specify the dependencies between operations (execution sequence)
Note: do not appear circular dependent!
15--set the number of simultaneous concurrent threads:
- [Self.myqueue Setmaxconcurrentoperationcount:2];
- for (int i = 0; i < ++i) {
- Nsblockoperation *op = [nsblockoperationblockoperationwithblock:^{
- [Self operationaction:@ (i)];
- }];
- [Self.myqueue Addoperation:op];
- }
Problem
Why does self in block code not cause a circular reference?
16--nsoperation Summary:
In essence, the performance of the operations queue is slightly lower than GCD, but in most cases this negative impact is negligible, and the operational queue is the preferred tool for concurrent programming
AFN, the ground floor with GCD development, the development of the interface is Nsoperation
17--runloop:
Run Loop provides a mechanism for executing code asynchronously and cannot perform tasks in parallel
In the main queue, main run loop works directly with the execution of the task, handling UI events, timers, and other kernel-related events
The main purpose of the run loop is to ensure that the thread that executes the program is not terminated by the system
Operating characteristics of the Run loop
- When an event occurs, the Run loop notifies the application to respond based on the specific event type
- When no event occurs, the Run loop goes into hibernation to save power
- When the event occurs again, the Run loop is woken up to handle the event
- Run loops in the main thread and other threads
- The main thread of the iOS program is configured with the run Loop by default
- Other threads do not have the run Loop set by default
Typically in development, runloop are rarely actively created, and events are usually added to the Runloop
18--circular references in multiple threads:
A circular reference is caused if the Self object holds a reference to an operand and the object directly accesses self.
Using self in a manipulation object alone does not cause circular references
Note: not available at this time (weakself)
19--resource sharing in multiple threads:
Many of the problems in concurrent programming are rooted in accessing shared resources in multiple threads. A resource can be a property, an object, a network device, or a file, etc.
Any shared resource in multiple threads can be a potential conflict point and must be carefully designed to prevent this conflict from occurring
20--Update UI:
- #pragma mark to set the text of the prompt message
- -(void) Setinfotext: (NSString *) InfoText
- {
- if (Infotext.length = = 0) {
- Self.infoTextView.text = @ "";
- Return
- }
- 1. Remove the contents of the current TextView
- nsmutablestring *STRM = [Self.infoTextView.text mutablecopy];
- 2. Append text
- [strmappendformat:@ "%@\n", InfoText];
- 3. Set the content in TextView
- Self.infoTextView.text = [StrM copy];
- 4. Scroll to the end of the text box
- Nsrange r = Nsmakerange (strm.length-1, 1);
- [Self.infotextview Scrollrangetovisible:r];
- }
Summary of 21--contribution resources:
To ensure performance, atomic only protects the property setter method.
When competing for shared resources, if the getter method of the attribute is involved, you can use the mutex @synchronized to ensure that the properties are safe to read and write between multiple threads
Whether it is atomic or @synchronized, the cost of use is high.
recommendation : Multithreading is the concurrent execution of multiple tasks to raise efficiency, if possible, should avoid competing for shared resources in the thread
It is for performance reasons that most of the classes in Uikit are not thread-safe, so Apple requires that updates to UI-related operations be performed in the main thread
Choice!
22--Single case:
Singleton mode is a common software design pattern.
The singleton mode can ensure that only one instance of a class is available in the system, and the instance is easy to be accessed, so as to control the number of instances and save system resources.
Singleton mode is the best solution if you want an object of a class in your system to exist only one
The most common singleton in iOS is uiapplication
Application Scenarios:
- Audio playback, background music!
- Hardware resources: Accelerators, [UIScreen Mainscreen]
- SHAREDXX, Mainxxx
Implementation steps
Overriding the Allocwithzone method
The Allocwithzone method is a method that is eventually called when an object allocates memory space, overriding the method, guaranteeing that only one memory space is allocated
Establish a Sharedxxx class method to facilitate access to other classes
- + (ID) allocwithzone: (struct _nszone *) zone
- {
- Staticticket *instance;
- staticdispatch_once_t Oncetoken;
- Dispatch_once (&oncetoken, ^{
- instance = [Super Allocwithzone:zone];
- });
- Returninstance;
- }
Summary:
Advantages
You can prevent other objects from instantiating a copy of a singleton object, ensuring that all objects have access to a unique instance
Disadvantages
Once a singleton object is established, the object pointer is stored in the static area, and the memory space allocated by the Singleton object in the heap will not be released until the application terminates.
Tips
Only objects that do need to be used only need to be considered in singleton mode and do not misuse a single case
23--nsobject Multithreading:
- How to open a background execution task
- -(void) Performselectorinbackground: (SEL) Aselectorwithobject: (ID) arg
- To notify the main thread of a method to perform a task in the background threads
- -(void) Performselectoronmainthread: (SEL) Aselectorwithobject: (ID) arg waituntildone: (BOOL) wait
- Get thread Information
- [Nsthread CurrentThread]
- Thread hibernation
- [Nsthread sleepfortimeinterval:2.0f];
Characteristics
- Simple to use, light-weight
- Cannot control the number of threads and the order of execution
Note:
NSObject's multithreaded approach uses Nsthread's multithreading technology
And Nsthread's multithreading technology does not automatically use @autoreleasepool
When using NSObject or nsthread multithreading technology, if object assignment is involved, you need to add the @autoreleasepool manually
24--@autoreleasepool:
Memory Management in IOS development
- In iOS development, there is no garbage collection mechanism in Java or C #
- With ARC development, the compiler automatically adds retain, release, and Autorelease based on the code structure at compile time
How the auto-release pool works
- Objects marked as autorelease are added to the most recently created auto-release pool after the scope has been scoped
- Release messages are sent to all objects in the auto-free pool when the auto-free pool is destroyed or exhausted
- Each thread needs to have @autoreleasepool, otherwise a memory leak may occur, but using nsthread multithreading technology does not create an auto-free pool for the background thread
Common cases:
- for (int i = 0; i < ++i) {
- Nsstring*str = @ "Hello World";
- str = [strstringbyappendingformat:@ "-%d", I];
- str = [struppercasestring];
- NSLog (@ "%@", str);
- }
Q: What are the problems with the above code? If the number of loops is very large, how should I modify it?
iOS development-Multi-threaded OC & Multithreading