How does GCD work?
Included in this article: https://juejin.cn/post/6976878024566243335
1. Serial queue, synchronous operation, no new thread will be created, and the operation will be executed in sequence;
Serial queue, asynchronous operation, new thread will be created, and the operation will be carried out in sequence,
Usage scenario: operations that do not affect the main thread and need to be executed in sequence;
2. Parallel queue, synchronous operation, no new county will be created, and the operation will be executed in sequence;
Parallel queues and asynchronous operations will create new threads, and the operations will be carried out in disorder. If there are other tasks before the queue, they will wait for other tasks to be executed;
The global queue is systematic and can be used directly by get
UI updates must be performed in the main thread,
Asynchronous operation of global queue will create new sub threads, and the operation will be executed out of order. If there are other tasks in front of the queue, it will wait for other tasks to be executed before calling;
The global queue synchronization operation will not create new threads and will be executed sequentially
All operations of the queue are executed by the main thread in sequence. There is no asynchronous concept. The synchronous operations added by the main queue will never be executed and will deadlock
Singleton mode
allocwithzone is the method that will eventually be called when the object allocates memory space. Rewrite this method to ensure that only one piece of memory will be allocated_ Once is thread safe, ensuring that the contents of the block code are executed only once
The synchronization operation added to the serial queue will deadlock, but the code before the nested synchronization operation will be executed;
The synchronization operations added to the parallel queue will not deadlock and will be executed in the main thread;
Synchronization operations added to the global queue do not deadlock.
The main purpose of synchronization operation is to block the execution of parallel queue tasks. Only after the current synchronization task is executed, the subsequent tasks will be executed. Application: user login
The difference between queue and thread:
Queue: it manages threads, which is equivalent to thread pool. It can manage when threads execute.
Queues are divided into serial queues and parallel queues
Serial queue: threads in the queue execute sequentially (not simultaneously)
Parallel queue: the threads in the queue will execute concurrently. There may be a question. Isn't the queue first in first out? If the subsequent tasks are completed, how do you get out. It should be emphasized here that after the task is executed, it may not be out of the queue. Only after the previous task is executed will it be out of the queue, that is to say, even if the execution is completed, you must wait until the previous task is executed and out of the queue before you can go out.
The main thread queue is also different from the queue created by GCD.
The main thread queue is different from the queue created by GCD.
The priority of the queue created in GCD is not as high as that of the main queue, so there are no nested tasks in the serial queue open synchronization task in GCD, which will not block the main thread. There is only one possibility that may lead to deadlock, that is, nested open tasks in the serial queue may lead to deadlock.
Synchronization cannot be enabled in the main thread queue, which will block the main thread.
Only asynchronous tasks can be started, and starting asynchronous tasks will not start new threads, but only reduce the priority of asynchronous tasks and call them when the cpu is idle. The synchronization task will preempt the resources of the main thread and cause deadlock.
Thread: there are many tasks (synchronous, asynchronous)
Difference between synchronous and asynchronous:
Synchronization tasks have high priority and have execution order in threads. New threads will not be started.
Asynchronous tasks have low priority and are executed in no order in the thread. It depends on whether the cpu is idle.
New threads will not be opened in the main queue, and new threads will be opened in other queues.
Main thread queue note:
- The following code execution sequence
- 1111
- 2222
Main queue asynchronous
<NSThread: 0x8e12690>{name = (null), num = 1}
Starting an asynchronous task in the main queue does not start a new thread, but still executes the code in the code block in the main thread. Why not block threads?
The main queue starts asynchronous tasks. Although it will not start new threads, it will lower the priority of asynchronous tasks. When it is free, it will execute asynchronous tasks on the main thread.
Why do threads block when synchronization tasks are started in the main queue?
Start the synchronization task in the main queue, because the main queue is a serial queue, and the threads in it are sequential. Only one thread is executed before the next thread is executed. However, there is always only one main thread in the main queue, and the main thread will not complete the execution, because it is an infinite loop, unless the application is closed. Therefore, when a synchronization task is started in the main thread, the synchronization task will want to seize the resources for execution, while the main thread task has been performing some operations and refuses to let go. Both have high priority, which eventually leads to deadlock and blocking threads.
- (void)main_queue_deadlock { dispatch_queue_t q = dispatch_get_main_queue(); NSLog(@"1111"); dispatch_async(q, ^{ NSLog(@"Main queue asynchronous %@", [NSThread currentThread]); }); NSLog(@"2222"); // The following will cause thread deadlock // dispatch_sync(q, ^{ // NSLog(@ "main queue synchronization% @", [NSThread currentThread]); // }); }
Synchronous tasks in parallel queues are executed in sequence, and only asynchronous tasks have no sequence;
The serial queue starts asynchronous tasks in order
After the asynchronous task is opened in the serial queue, the nested synchronous task causes deadlock
- (void)serial_queue_deadlock2 { dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", DISPATCH_QUEUE_SERIAL); dispatch_async(q, ^{ NSLog(@"Asynchronous task %@", [NSThread currentThread]); // Deadlock caused by opening synchronization below: because threads in the serial queue have execution order, the synchronization tasks opened below will not be executed until the asynchronous tasks opened above have been executed. While the above asynchronous task has not been executed, it will not be executed until the curly braces below, and the following synchronous task is already preempting resources, and a deadlock will occur. dispatch_sync(q, ^{ NSLog(@"Synchronization task %@", [NSThread currentThread]); }); });
After the serial queue opens the synchronization task, the nested synchronization task causes a deadlock
- (void)serial_queue_deadlock1 { dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", DISPATCH_QUEUE_SERIAL); dispatch_sync(q, ^{ NSLog(@"Synchronization task %@", [NSThread currentThread]); // Deadlock caused by opening synchronization below: because threads in the serial queue have execution order, the synchronization tasks opened below will not be executed until the synchronization tasks opened above are executed. While the above synchronization task has not been executed, it will not be executed until the curly braces below, and the following synchronization task is already preempting resources, and a deadlock will occur. dispatch_sync(q, ^{ NSLog(@"Synchronization task %@", [NSThread currentThread]); }); }); NSLog(@"Synchronization task %@", [NSThread currentThread]); } Nested asynchronous tasks will not cause deadlock after the serial queue opens synchronous tasks
Network:
PUT method
PUT
- Unlimited file size
- Can overwrite file
POST
- There is usually a limit of 2M
- New file, cannot duplicate name
BASE 64 is the most commonly used coding format in network transmission - the coding method used to encode binary data into strings
Usage of BASE 64:
1> Able to encode and decode
2> It is used as the basic algorithm by many encryption algorithms
Audio processing
Dependent frameworks: AVFoundation, AudioToolbox framework
Play long music: AVAudioPlayer
Play short sound effect: load audio file to generate SystemSoundID
Recording: AVAudioRecord
Low level and advanced audio / video processing
CoreAudio and CoreVideo framework
Working principle of XMPP
The node is connected to the server
The server authenticates it with a certificate in the local directory system
The node specifies the target address and lets the server inform the target status
Servers find, connect, and authenticate with each other
Interaction between nodes
Main extension functions provided by XMPP framework
XMPPReconnect: automatically reconnects the XMPP stream if it is interrupted unexpectedly
XMPPRoster: Standard XMPP roster
XMPPRoom: provides multiplayer chat support
XMPPPubSub: provides public subscription support
Communication category and public XML attribute
The real-time messaging system using XMPP includes three communication categories:
Messaging, where data is transmitted between interested parties
Online status, allowing users to broadcast their online status and availability
An information / query request that allows an XMPP entity to initiate a request and receive a response from another entity
All three types of XMPP sections have the following public properties:
from: JID of the source XMPP entity
to: JID of target recipient
id: optional identifier of the current conversation
type: optional subtype of the section
xml:lang: if the content is human readable, it is the description of the message language
XMPP core file
XMPPStream: it is the main interactive class in the development process. All extension and user-defined codes should be based on this class
XMPPParser: used for XMPPStream parsing
XMPPJID: provides an implementation of immutable JID, which complies with NSCopying protocol and NSCoding protocol
XMPPElement: the base class of the following three XMPP elements
XMPPIQ: request
XMPPMessage: message
XMPPPresence: attend
XMPPModule: used when developing XMPP extensions
XMPPLogging: the logging framework of XMPP
XMPP internal: the core and high-level underlying content used within the entire XMPP framework
Common extensions of XMPP framework
XEP-0045: multi user chat
XEP-0060: publish subscribe
XEP-0065: SOCKS5 byte stream
XEP-0085: chat status notification
XEP-0096: file transfer
XEP-0172: user nickname
XEP-0184: message delivery
CoreDataStorage: data store
Reconnect: reconnect
Roster: roster
Frame of XMPP column
Cocoa lumberjack: logging framework
CocoaAsyncSocket: the underlying network framework, which realizes asynchronous Socket network communication
Cfnetwork & security framework dependency needs to be added
KissXML: XML parsing framework
Libxml2.0 needs to be added Dylib framework dependency
The following compilation options need to be specified:
OTHER_LDFLAGS = -lxml2 HEADER_SEARCH_PATHS = /usr/include/libxml2 libidn
Differences between global queues and parallel queues
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1> You don't need to create it, you can use it directly
2> The execution effect of the two queues is the same
3> The global queue has no name. When debugging, the exact queue cannot be confirmed
4> The global queue has a high default priority
Parallel queue
dispatch_queue_t q = dispatch_queue_create("ftxbird", DISPATCH_QUEUE_CONCURRENT);
Serial queue
dispatch_queue_t t = dispatch_queue_create("ftxbird",DISPATCH_QUEUE_SERIAL);
In development, track the current thread
[NSThread currentThread]
Task nesting example of parallel queue
dispatch_queue_t q = dispatch_queue_create("ftxbird", DISPATCH_QUEUE_CONCURRENT); // Task nesting dispatch_sync(q, ^{ NSLog(@"1 %@", [NSThread currentThread]); dispatch_sync(q, ^{ NSLog(@"2 %@", [NSThread currentThread]); dispatch_sync(q, ^{ NSLog(@"3 %@", [NSThread currentThread]); }); }); dispatch_async(q, ^{ NSLog(@"4 %@", [NSThread currentThread]); }); NSLog(@"5 %@", [NSThread currentThread]); });
Main queue (thread)
1> Each application has only one main thread
2> All UI updates must be executed on the main thread!
3> The main thread works all the time, and unless the program is killed, the work of the main thread will never end!
dispatch_queue_t q = dispatch_get_main_queue();
Example of updating UI on main queue
//Create code block void (^TaskOne)(void) = ^(void) { NSLog(@"Current thread = %@", [NSThread currentThread]); NSLog(@"Main thread = %@", [NSThread mainThread]); [[[UIAlertView alloc] initWithTitle:@"GCD" message:@"Great Center Dispatcher" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] show]; }; //Get distribution queue dispatch_queue_t mainQueue = dispatch_get_main_queue(); //Submit task dispatch_async(mainQueue, TaskOne); } //Simple writing method dispatch_async( dispatch_get_main_queue(), ^(void) { NSLog(@"Current thread = %@", [NSThread currentThread]); NSLog(@"Main thread = %@", [NSThread mainThread]); [[[UIAlertView alloc] initWithTitle:@"GCD" message:@"Great Center Dispatcher" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] show]; });
NSOperation multithreading technology
NSBlockOperation is easy to use
//Custom queues are generally defined as attributes in development @property (nonatomic, strong) NSOperationQueue *myQueue; self.myQueue = [[NSOperationQueue alloc] init];
1> In a custom queue
NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{NSLog(@"%@", [NSThread currentThread]);}];
All custom queues run in child threads
[self.myQueue addOperation:block];
Or:
[self.myQueue addOperationWithBlock:^{NSLog(@"%@", [NSThread currentThread]);}];
2> Execute in main queue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{NSLog(@"%@", [NSThread currentThread]);}];
NSInvocationOperation is easy to use
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demoOp:) object:@"hello op"]; - (void)demoOp:(id)obj { NSLog(@"%@ - %@", [NSThread currentThread], obj); }
The performSelectorOnMainThread method uses
// 1> Analog download, delay [NSThread sleepForTimeInterval:1.0]; // 2> To set the image, the performSelectorInBackground method is allowed // Updating the UI in the background thread is strongly not recommended! // YES blocks the thread until the method is called // NO will not block the thread and will continue to execute [self performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageNamed:imagePath] waitUntilDone:NO]; // 1. Image - (void)setImage:(UIImage *)image { self.imageView.image = image; [self.imageView sizeToFit]; }
Question: what's wrong with the code? What happens if the number of cycles is very large? How should I modify it?
// Solution 1: if i is large, you can @ autoreleasepool after the for loop // Solution 2: if i play hard, one cycle will cause The automatic release pool is full,One cycle@autoreleasepool for (int i = 0; i < 10000000; ++i) { @autoreleasepool { // * NSString *str = @"Hello World!"; // new * str = [str uppercaseString]; // new * str = [NSString stringWithFormat:@"%@ %d", str, i]; NSLog(@"%@", str); } }