Remnant of iOS interview - exorcism sword spectrum

Posted by soto134 on Wed, 26 Jan 2022 08:03:17 +0100

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

  1. Unlimited file size
  2. Can overwrite file

POST

  1. There is usually a limit of 2M
  2. 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);
        }
    }

Recommendation at the end of the article: iOS popular anthology & video analysis

① Swift

② iOS underlying technology

③ iOS reverse protection

④ iOS interview collection

⑤ Large factory interview questions + bottom technology + reverse Security + Swift

Topics: Swift iOS xcode objective-c