1. INTERVIEW ‘
2. The iOS developers direction
3.INTERVIEW QUESTION
1. Deep copy and shallow copy
- Shallow copy:
1. Copy memory addresses so that the target object pointer and source object point to the same memory space. When memory is destroyed, the pointer to this space needs to be redefined before it can be used, otherwise it will become an wild pointer 3. Copy the pointer to the original object and add +1 to its reference count. 4. Create a new pointer to the original object, but do not create a new object.
- Deep copy:
2. After the copy is complete, the two objects have the same value but different memory addresses. 3. The two objects have no relationship whatsoever
- Essential differences:
1. A deep copy is a content copy, and a shallow copy is a pointer copy. 2. Whether reference counting of memory addresses is affected.
-
Case a
NSString * str1 = @”copyStr”;
NSMutableString *str2 = [str1 copy];
NSMutableString *str3 = [str1 mutableCopy];
NSLog(@”str1:%p–%@”,str1,str1);
NSLog(@”str1:%p–%@”,str2,str2);
NSLog(@”str1:%p–%@”,str3,str3);
2018-04-14 14:50:54.117652+0800 mutycopy-copy [2644:63575] STR1:0x109a48068 --copyStr 2018-04-14 14:50:54.117885+0800 Mutycopy-copy [2644:63575] str1:0x109a48068--copyStr 2018-04-14 14:50:54.118010+0800 MutyCopy [2644:63575] str1:0x600000259a40--copyStrCopy the code
2. Copy of NSString is a shallow copy, and the object returned by copy is an immutable object. 3
* Case 2:
NSMutableString * str1 = [NSMutableString stringWithString:@"mutableStr"];
NSMutableString * str2 = [str1 copy];
NSMutableString * str3 = [str1 mutableCopy];
NSLog(@"str:%p-----%@",str1,str1);
NSLog(@"str:%p-----%@",str2,str2);
NSLog(@"str:%p-----%@",str3,str3);
Copy the code
2018-04-14 15:04:50.092820+0800 mutycopy-copy [2685:70866] STR :0x60000025b210-----mutableStr 2018-04-14 15:04:50.093059+0800 mutycopy-copy [2685:70866] STR :0x60000022ca40-----mutableStr 2018-04-14 15:04:50.093217+0800 MutyCopy-Copy[2685:70866] str:0x60000025b540-----mutableStrCopy the code
2.NSMutableString copy and mutableCopy are both deep copies. 3
4.2 Starting an iOS Program
- First, find the program entry and execute the main function
- main –>> UIApplicationMain
- Create a UIApplication object
- Create a PROXY object for UIApplication and assign a value to the proxy property of UIApplication object
- Open the main run loop to receive events and keep the program running
- Load info.plist, determine if main.storyboard is specified, and if it is, load it.
4.3 loadView
- When is it called?
Every time you access a VC view and the view is nil, the loadView method is called
- role
The loadView method is used to create the VIEW responsible for the VC.
- What is the default implementation?
The default implementation is [spuer loadView] 1. It looks for the XIB file associated with the UIViewController and loads the XIB file to create the VC’s view2. If VC specifies the xiB file name during initialization, the xiB file will be loaded according to the xiB file name passed in. If there is no obvious XIB file name, the xiB file with its own name is loaded. 3. If no associated XIB file is found, a blank UIView is created and assigned to the VC’s View property
4.4 Singleton Mode
4.5 a multithreaded
- process
1. A process is an application program that is running in the system. 2. Each process is independent and runs in its own dedicated and protected memory space.
- thread
1.1 In order for a process to execute a task, it must have threads. Each process must have at least one thread. A thread is the basic execution unit of a process. All the primary tasks of a process are executed in a thread
- multithreading
1.1 Multiple threads can be started in a process, and each thread can perform different tasks in parallel (simultaneously) 2. 3. Multiple threads can improve the efficiency of program execution
For example, let’s open two threads simultaneously to download file A and file B.
- Principle of multithreading
1. The CPU can process only one thread at a time, and only one thread is working 2. Multi-threaded concurrent execution, is the CPU quickly scheduling between multiple threads switch
Note: What happens if there are very, very many threads?
The CPU will schedule between multiple threads, consuming a lot of CPU resources. In this case, each thread will be scheduled to execute less frequently and the execution efficiency of the thread will be reduced.
- Advantages and disadvantages of multithreading
1. Advantages: 1.1. Can properly improve the execution efficiency of the program 1.2. Disadvantages: 2.1. Starting threads requires a certain amount of memory space. If a large number of threads are started, a large amount of memory space will be occupied and the performance of the program will be reduced.
- Multithreaded application
1. What is the main thread? After an iOS program is run, one thread is started by default, which is called main thread 2. What is the main function of the main thread? 2.1. Display/Refresh UI 2.2. Handle UI Events 3. 3.1. Do not put time-consuming operations into the main thread 3.2. Time-consuming operations will jam the main thread and seriously affect the smoothness of the UI 4. Multi-threaded implementation of technical solutions? Pthread NSThread, GCD, NSOperation 4 scheme.
4.6 NSThread
- Create and start the thread
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadFun) object:nil];
[thread start];
Copy the code
Once the thread is started, it tells the CPU that it is ready to accept CPU scheduling at any time. After the CPU schedules the current thread, it executes self’s run method in thread
- Main thread usage
- Other ways to create a thread
The thread is automatically started when it is created
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
Copy the code
Implicitly creates and starts the thread
[self performSelectorInBackground:@selector(run) withObject:nil];
Copy the code
- Thread state
1. Start the thread,start. Ready state –>> Running state. 2. Block (pause) the thread and enter the blocked state
+ (void)sleepUntilDate:(NSDate *)date;
Copy the code
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
Copy the code
3. Force the stopped thread to enter the dead state
Note: Once the thread has stopped, the task cannot be started again.
- Multi-threaded security hazards
1. Resource sharing A resource may be shared by multiple threads, that is, multiple threads may access the same resource. When multiple threads access the same resource, it is easy to cause data confusion and data security problems.2. As shown in figure,
If more than one thread accesses the same resource, it will cause data disorder. What should we do about it?
image
3. Thread A and thread B access the resource variable Integer at the same time. To prevent resource looting, thread A uses A lock before reading the resource variable Integer, completes the data operation in thread A (17+1=18), and writes the data to Integer. Unlock. When thread A operates on Integer, thread B does not have access to Integer. Thread B can access the resource variable Integer.4 only after thread A_Unlock. The mutex uses the format @synchronized(self){// code that needs locking}
Note: Only 1 lock is used to lock 1 minute code, using more than one lock is invalid
5. Advantages and disadvantages of mutex Prerequisite for use of mutex: Multiple threads compete for the same resource Advantage: it can effectively prevent data security problems caused by multiple threads competing for resources Disadvantage: it consumes a large amount of CPU
Nonatomic and atomic properties are thread-safe and require a lot of resources to lock setter methods (the default is atomic)
4.7 the GCD
- What is the communist party?
The full Grand Central Dispatch, a pure C language for the Central scheduler, provides a lot of powerful functions
- The advantage of the GCD
GCD is Apple’s solution for multi-core parallel computing. 2.GCD automatically utilizes more CPU cores.
- The COMMUNIST Party has two core concepts
1. Task: What operation to perform 2. Queue; For storing tasks
- Tasks and Queues
1. Perform the task
There are two functions in GCD that are used to perform tasks
1.1 Synchronizing Tasks
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block); Queue: queue block: taskCopy the code
1.2 Perform tasks asynchronously
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
Copy the code
1.3 Differences between Synchronization and Asynchronous Synchronization: Tasks can be executed only in the current thread, without the ability to start a new thread. Asynchronous: Tasks can be executed in a new thread, with the ability to start a new thread
- Type of queue
GCD queues can be divided into two main types of concurrent queues: sequential queues that allow multiple tasks to be executed concurrently (concurrent functions are only valid with asynchronous functions) : serial queues that allow tasks to be executed one after the other
- Confusing terminology
There are four confusing terms: synchronous, asynchronous, concurrent, and serial
Note: Synchronization function + main queue == deadlock
- Concurrent queue
By default, GCD already provides a global concurrent queue for use by the entire application. There is no need to manually create a global concurrent queue using the dispatch_get_global_queue function
Dispatch_queue_t Dispatch_geT_global_queue (dispatch_queue_priority_t priority, queue priority unsigned long flags);Copy the code
Dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);Copy the code
- Serial queues
1. Use the dispatch_queue_create function to create a serial queue
Dispatch_queue_t = dispatch_queuE_CREATE (const char*label, dispatch_queuE_attr_t attr); Queue attribute, usually NULLCopy the code
2. Tasks placed in the main queue using the main queue are executed on the main thread using dispatch_get_main_queue() to obtain the main queue
dispatch_queue_t queue = dispatch_get_main_queue();
Copy the code
- Return to main thread from child thread
Dispatch_async (dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{Execute time-consuming asynchronous operations... Dispatch_async (dispatch_get_main_queue(), ^{return to main thread, perform UI refresh}); });Copy the code
- Delay to perform
After setting the delay, it will execute the rest of the code first, and then call self’s run method after 2 seconds (without getting stuck in the main thread, it will return to the main thread at the end of the main thread call, and return to the child thread at the end of the child thread call).
WithObject: afterDelay: the delay time [self performSelector:@selector(run) withObject:nil afterDelay:2.0];Copy the code
Use the GCD function (2 seconds later, automatically start the new thread to execute the code in the block, will not card the main current thread, in the main/child thread call can be used)
2 * NSEC_PER_SEC: specifies the number of seconds to be set. Dispatch_get_main_queue (): specifies the main queue Dispatch_after (dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), ^{execute the code here after 2 seconds... In which thread, depending on the queue type});Copy the code
3. The main thread will be stuck
[NSThread sleepForTimeInterval:3]
Copy the code
- Only execute it once
Using the “dispatch_once” function ensures that a piece of code is executed only once during the course of the program. In design mode, you can also use singleton mode
static dispatch_once_t onceToken; Dispatch_once (&onceToken, ^{code that is executed only once during execution (thread safe by default)});Copy the code
- Queue group
Requirements :1. Perform two time-consuming operations asynchronously, and then return to the main thread to perform the operation after the two asynchronous operations are completed
dispatch_group_t group = dispatch_group_create(); Dispatch_group_async (group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{Execute one asynchronous operation}); Dispatch_group_async (group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{Execute one asynchronous operation}); Dispatch_group_notify (group, dispatch_get_main_queue(), ^{ });Copy the code
- GCD creation and release
Prior to iOS6.0, whenever an object was created in GCD using a function with the word creat, it should be released once. After iOS6.0,GCD was incorporated into the memory management mechanism of ARC, and when using GCD we treat it like a normal OC object, so we no longer need to call the release method.
- Basic use of THE GCD
image
1. Asynchronous functions + concurrent queues
1. Create a queue (concurrent queue) dispatch_queue_t queue = dispatch_queue_CREATE ("com.baidu. WWW ", DISPATCH_QUEUE_CONCURRENT); Dispatch_async (queue, ^{NSLog(@"1-- %@",[NSThread currentThread]); });Copy the code
2. Asynchronous functions + serial queues
1. Create a queue (serial queue). Dispatch_queue_t queue = dispatch_queue_CREATE ("com.baidu. Dispatch_async (queue, ^{NSLog(@"1-- %@",[NSThread currentThread]); });Copy the code
3. Sync function + serial queue
1. Create a queue (serial queue). Dispatch_queue_t queue = dispatch_queue_CREATE ("com.baidu. For queue, ^{NSLog(@"1-- %@",[NSThread currentThread]); });Copy the code
4. Synchronous function + concurrent queue
Dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // Synchronize function dispatch_sync(queue, ^{NSLog(@"1-- %@",[NSThread currentThread]); });Copy the code
5. Asynchronous function + main queue
1. Obtain the main queue dispatch_queue_t queue = dispatch_GET_main_queue (); Dispatch_async (queue, ^{NSLog(@"1-- %@",[NSThread currentThread]); });Copy the code
6. Sync function + main queue
1. Obtain the main queue dispatch_queue_t queue = dispatch_GET_main_queue (); dispatch_sync(queue, ^{ NSLog(@"1---%@",[NSThread currentThread]); });Copy the code
4.8 NSOperation
- NSOperation role?
Using NSOperation and NSOperationQueue together can also achieve multi-threaded programming
- NSOperation and NSOperationoQueue to implement multithreading steps
- A subclass of NSOperation
NSOperation is an abstract class and does not have the ability to encapsulate operations. You must subclass NSInvocationOperation in three ways: 1.NSInvocationOperation 2. Custom subclasses inherit from NSOperation to implement internal response methods
- NSInvocationOperation
1. Create an object
- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
Copy the code
2. Call the start method to start the operation
- (void)start;
Copy the code
Once the operation is performed, the SEL method of target is called
By default, a call to start does not open a new thread to perform the operation. Instead, the operation is synchronized to the current thread. The operation is executed asynchronously only if the NSOperation is placed in an NSOperationQueue
- NSBlockOperation
1. Create an NSBlockOperation object
+ (id)blockOperationWithBlock:(void (^)(void))block;
Copy the code
Add more operations with the addExecutionBlock: method
- (void)addExecutionBlock:(void (^)(void))block;
Copy the code
As long as the operand encapsulated by NSBlockOperation is greater than 1, the operation is performed asynchronously
- NSOperationQueue role
If you add NSOperation to the NSOperationQueue, the system automatically performs the operations in the NSOperationQueue asynchronously
- (void)addOperation:(NSOperation *)operation;
- (void)addOperationWithBlock:(void (^)(void))block;
Copy the code
- Maximum concurrency
Number of concurrent tasks Methods related to the maximum number of concurrent tasks
-(NSInteger)maxConcurrentOperationCount;
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
Copy the code
- Custom NSOperation
Override -(void)main to implement the task you want to execute. Override -(void)main to create the automatic release pool automatically. If the operation is asynchronous, the automatic release pool cannot be accessed
4.9 RunLoop
- If there is no RunLoop, the program outputs and exits
int main(int argc, char * argv[]) {
NSLog(@"main");
return 0;
}
Copy the code
- If you have RunLoop, the program doesn’t exit immediately, since RunLoop is started in main
int main(int argc, char * argv[]) { BOOL run = YES; Do {// perform various tasks, handle various events}while(run); return 0; }Copy the code
- The main function of the RunLoop, UIApplicationMaiin function starts a RunLoop inside, so the UIApplicationMain function has not been returned, keep the program continues to run, the default boot RunLoop is associated with the main thread
int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); }}Copy the code
- RunLoop with thread
Each thread has a unique RunLoop object. 2. The RunLoop of the main thread is created automatically, and the RunLoop of the child thread needs to be created actively
- Get the RunLoop object
- RunLoop related classes
The RunLoop classes in Core Foundation are: CFRunLoopRef: itself, which also represents a RunLoop object. CFRunLoopModeRef: the running mode of the RunLoop. CFRunLoopSourceRef: the event source CFRunLoopbaserverRef: The observer listens for the status of CFRunLoopRef
- CFRunLoopModeRef
The system registers five modes by default: KCFRunLoopDefaultMode: the default Mode of the App, usually the main thread is run in this Mode UITrackingRunLoopMode: Interface tracking Mode, to ScrollView tracking touch sliding, guarantee the interface slip is not affected by other Mode UIInitializationRunLoopMode: When just start the App the first to enter the first Mode, after the completion of the start will no longer use GSEventReceiveRunLoopMode: accept system internal Mode of events, usually in less than kCFRunLoopCommonModes: This is a placeholder Mode, not a real Mode
- RunLoop processes the logic
image
1. Notify the observer that the Loop is about to enter 2. Notify the observer that timer 3 is about to be processed. Notifies the observer that non-port-based sources will be processed 4. Process non-port-based sources 5. If a port-based source is ready and in the wait state, start immediately and skip to step 9 6. Inform the observer that the thread is about to sleep 7. Hibernate and wait to wake up 8. Inform the observer that the thread has just been awakened 9. Process the message received at wake up, and then skip to Step 2 10. Notify the observer that Loop is coming
- RunLoop application
- RunLoop interview questions
1. What is a RunLoop? The running loop is essentially a do-while loop that processes tasks (such as Source,Timer,Observer); Each thread corresponds to a RunLoop. The RunLoop of the main thread is started by default, and the RunLoop of the subthread is started manually. RunLoop can only select one Mode to start. If there is no Source Timer in the current Mode, RunLoop will exit directly.
4.10 HTTP Communication Process – Request/Response
According to the HTTP protocol, a complete HTTP request sent by the client to the server contains the following contents