1: What is the difference between classification and extension? What can be used for? What are the limitations of classification? What are the members of the classification structure?

  • Classification is mainly used to add methods, attributes and protocols for a class (generally used to expand methods for the system class or to separate a complex class into different files according to its functions).
  • Extensions are used mainly for member variables, attributes, and methods that a class does not already have. Note: Methods are declarations only (I usually use them to extend private properties, or to override or write read-only properties of.h).

The difference between classification and extension

  • Classification is merged into the class information at run time, and extension is merged into the class at compile time
  • Properties of a classification declaration only generate declarations of setter/getter methods, and do not automatically generate member variables and implementations of getter/setter methods, whereas extensions do
  • Classes are not available to add instance variables to classes, extensions can
  • Classes can add implementations of methods to classes, whereas extensions can only declare methods, not implementations

Limitations of classification

  • Note: The memory management of the associated object does not have weak. When using the associated object, we need to pay attention to the problem of wild Pointers. We can implement it through other methods
  • Methods that have the same name as the original implementation of the class override the implementation of the original method.
  • Multiple classes with the same method name invoke the implementation of the last compiled class

What are the members of the structure of the classification

const char *name; // name classref_t CLS; Struct method_list_t *instanceMethods; Struct method_list_t *classMethods; Struct protocol_t *protocols; Struct property_list_t *instanceProperties; Struct property_list_t *_classProperties; // Class attribute list};Copy the code

2: difference between HTTPS and HTTP

HTTPS = HTTP +SSL/TLS

  • SSL, short for Secure Sockets Layer, is a security protocol that provides security and data integrity for network communication.
  • TLS stands for Transport Layer Security

That HTTPS is secure HTTP

  • HTTPS: Hyper Text Transfer Protocol Secure HTTPS: Hyper Text Transfer Protocol Secure HTTPS: Hyper Text Transfer Protocol Secure Is provided by TLS (SSL)! That’s probably what a library called OpenSSL provides. HTTPS and HTTP are both application layer protocols based on TCP (and UDP), but are completely different. TCP uses port 80 and HTTPS uses port 443 (QUIC is not based on TCP, but uses port 443). Also used for HTTPS). Conclusion: HTTPS is similar to HTTP, but more secure.
  • HTTPS requires you to apply for a certificate from a CA. Generally, there are few free certificates
  • HTTP is a hypertext transmission protocol. Information is transmitted in plain text. HTTP is a secure SSL encryption transmission protocol
  • HTTP connections are simple and stateless

3: Talk about the implementation mechanism of atomic; Why can’t we guarantee absolute thread-safety (preferably in context)?

Atomic implementation mechanism

  • Atomic is one of the property modifiers, meaning atomic, and is used as @property(atomic)int age; The compiler automatically generates getter/setter methods and eventually calls objc_getProperty and objc_setProperty methods to access the property.

  • Os_unfair_lock is used to lock both methods to ensure atomicity of reads and writes. Locks are stored in PropertyLocks (8 on iOS and 64 on MAC), and are initialized before being used. When needed, the locks are retrieved from PropertyLocks using the address of the object plus the offset of the member variable as key. Because the same lock is used to access the property, atomic can guarantee thread-safe access to the property.

Note: Since locks are finite, it is possible to read different properties using the same lock without using objects

Why can’t Atomic guarantee absolute thread-safety?

  • Atomic locks in getter/setter methods to keep access thread safe, assuming our property is @Property (atomic)NSMutableArray *array; With mutable containers, there is no guarantee that changes to the container will be thread-safe.

  • The compiler automatically produces getter/setter methods that eventually call objc_getProperty and objc_setProperty methods to access properties. Inside this method, thread-safe reading and writing is ensured. When we override getter/setter methods, You’re going to have to do your own thread safety in the getter/setter

4: What data structure is used by Autoreleasepool? Is the AutoreleasePoolPage structure understood?

  • Autoreleasepool is made up of multiple AutoreleasepoolPages that are connected in a bidirectional linked list.

  • The basic principle of Autoreleasepool is as follows: When each Autoreleasepool pool is created, a marker bit is set in the current AutoreleasePoolPage. During this time, objects are added to AutoreleasePoolPage when an object calls autorelsease

  • If the current page is full, a new page is initialized, then linked with a bidirectional list, and the newly initialized page is set to hotPage. When the pool POP is automatically released, pop from the bottom up, calling the release method of each object until the flag bit is reached.

The AutoreleasePoolPage structure is as follows

class AutoreleasePoolPage { magic_t const magic; id *next; Pthread_t const thread; //AutoreleasePoolPage thread AutoreleasePoolPage * const parent; // AutoreleasePoolPage *child; // Uint32_t const depth; Uint32_t hiwat; // Uint32_t hiwat; }Copy the code

Autoreleasepool role

@autoreleasepool{// Block-wide operations}Copy the code

The @Autoreleasepool function is to control the application’s peak memory (the maximum amount of memory that can be used at a particular time in the application) so that it does not become too high

What scenarios use Autoreleasepool?

  • When a program is run on the command line
  • Write loops that contain a large number of temporarily created objects
  • Creating a worker thread
  • A task that runs in the background for a long time

There is some overhead associated with automatic release pooling, so do not use it arbitrarily

5:TCP why three handshakes, four waves?

Three-way handshake

  • The client sends a SYN packet with syn=1 and SEq = X to the server, and then enters the SYN_sent state to the client
  • The server replies to the client with syn=1, SEq = Y, ACK =1, ACK = X +1 and enters the SYN_RCVD state
  • After receiving the confirmation packet, the client sends an acknowledgement packet to the server, ack=1, ACK =y+1. The client enters established. After receiving the acknowledgement packet, the server also enters Established

Four times to wave

  • The client sends a close link to the server and stops sending data
  • The server receives the request to close the link, sends a response to the client, I know, and then stops receiving data
  • When the server ends sending data, it sends a close link to the client and stops sending data
  • When the client receives the request to close the link, it sends a response to the server, I know, and then stops receiving data

Why three handshakes

  • In case the invalid connection request packet is suddenly sent to the server and an error occurs, it is assumed that this is an invalid packet segment. However, after the server receives the invalid connection request packet, it mistakenly thinks that the client sends a new connection request and sends a confirmation packet to the client, agreeing to establish a connection. Assuming that the “three-way handshake” is not used, a new connection is established as soon as the server sends an acknowledgement. Since there is no request from the Client to establish a connection, the client ignores the server’s confirmation and does not send data to the server, but the server assumes that the new transport connection has been established and waits for the CLENET to send data. The server’s resources are wasted

Why four waves

Because TCP is duplex communication, it may send data to the client when receiving the closing request from the client. Therefore, it cannot respond to the closing request and send the closing request at the same time

6: the difference between symmetric encryption and asymmetric encryption? Which algorithms are implemented respectively?

Symmetric encryption, encryption and decryption can use the same key

  • Asymmetric encryption: a public key and a private key are used for encryption and decryption. The public key is available to all. After obtaining the public key of the receiver, the sender can use the public key to encrypt the communication, and the receiver can use the private key to decrypt the communication.
  • The algorithms commonly used for symmetric encryption are AES,ChaCha20 and DES, but DES is considered to be insecure. The algorithms for asymmetric encryption are RSA and ECC

IOS encryption-related algorithm framework: CommonCrypto.

1: Symmetric encryption: DES, 3DES, and AES

  • Encryption and decryption use the same key.

  • Encryption and decryption process:

Plaintext -> key encryption -> ciphertext,

Ciphertext -> Key decryption -> plaintext.

Advantages: open algorithm, less computation, fast encryption speed, high encryption efficiency, suitable for mass data encryption;

Disadvantages: The two parties use the same key. The key transmission process is insecure and easy to crack. Therefore, the key needs to be changed frequently to keep it secret.

AES: The Advanced Encryption Standard (AES) is the next generation encryption algorithm standard. It supports encryption with 128, 192, and 256-bit keys. The encryption and decryption keys are the same. IOS generally uses ECB mode with 16-byte 128-bit key.

AES algorithm mainly includes three aspects: round change, turn number and key expansion.

Advantages: High performance, high efficiency, flexible and easy to use, high security level.

Disadvantages: Encryption and decryption of the same key, so the use of AES encryption, how to safely save the key becomes a problem.

DES: indicates the Data encryption standard. The entry parameters of the DES algorithm are Key, Data, and Mode.

Key is the working Key of the DES algorithm, consisting of 7 bytes and 56 bits. Data is 8 bytes and 64 bits, which is the Data to be encrypted or decrypted. Mode Indicates the working Mode of DES, including encryption and decryption.

Disadvantages: Less security than AES.

3DES: 3DES is a mode of the DES encryption algorithm. It uses three 64-bit keys to encrypt data for three times. DES is the encryption algorithm to AES transition, is a more secure transformation of DES. It takes DES as the basic module and designs a packet encryption algorithm by combinatorial packet method.

Asymmetric encryption :RSA encryption

  • Asymmetric encryption algorithms require two keys in pairs, a publickey and a privatekey.

** Encryption and decryption process: ** For a private key, there is only one corresponding public key. The generator is responsible for generating the private and public keys, saving the private keys, and publicizing the public keys. Public key encryption, private key decryption; Or private key digital signature, public key authentication. Public and private keys are paired and decrypt each other.

Features:

  • 1). ** Keeps information confidential to prevent the middle man attack: ** encrypts the plaintext through the receiver’s public key and transmits it to the receiver. Because only the receiver has the corresponding private key, others cannot have or calculate the private key through the public key, so the transmission process cannot be intercepted by the middle man. Only the recipient with the private key can read it. This method is typically used to exchange symmetric keys.
  • 2). * * authentication and prevent tampering with: * * permissions with its own private key to encrypt a dog license expressly, and will authorize plaintext and encrypted cryptograph, as well as the public key along with, the receiver will need only through the public key cipher decryption and authorization after clear contrast are consistent, can determine whether expressly on the way to be tampered with. This method is used for digital signatures.
  • ** Advantages: ** encryption strength is small, long encryption time, often used for digital signature and encryption key, very high security, to solve the security problem of symmetric encryption to save the key.
  • ** Disadvantages: ** encryption and decryption speed is much slower than symmetric encryption, not suitable for mass data encryption.
  1. Hash encryption: MD5 encryption,.SHA encryption, HMAC encryption

Hash algorithm encryption is used to encrypt data using the hash algorithm. The encrypted result is irreversible, that is, the encrypted data cannot be decrypted. ** Features: ** irreversible, open algorithm, the same data encryption results. ** Function: ** Information summary, information “fingerprint”, used to do data identification. For example, user password encryption, file verification, digital signature, and authentication protocol. MD5 encryption: ** Encrypts different data to result in fixed-length 32-bit characters.

SHA encryption: ** Secure hash algorithm, mainly applicable to the digital signature algorithm (DSA) defined in the Digital Signature Standard (DSS). For messages less than 2^64 bits in length, SHA1 produces a 160-bit message digest. When a message is received, the message digest can be used to verify data integrity. As the data is likely to change during transmission, different message digests will be generated. Of course, there are SHA256 and SHA512 in addition to SHA1.

**HMAC encryption: ** Given a key, do two hashes on plaintext encryption, and the result is still a 32-bit string.

  1. Base64 encryption

An encoding method that is not, strictly speaking, an encryption algorithm. Its function is to encode binary data into text, convenient network transmission.

Encoding in Base64 increases the length of the data by about a third, but the benefit is that the encoded data can be displayed directly in emails and web pages.

Although Base64 can be used as encryption, but base64 can be reversed, very insecure!

Base64 encoding has a very distinctive feature, the ‘=’ sign at the end.

7:HTTPS handshake process? Why should asymmetric encryption be used for key transfer? Two-way authentication understand?

The HTTPS handshake flow is shown below, taken from the diagram HTTP

  1. The client sends a Client Hello packet to start SSL communication. The packet contains the SSL version supported by the client and the list of encryption components.
  2. After receiving the packet, the server responds with a Server Hello packet. Like the client, the packet contains the SSL version supported by the client and a list of encryption components. The server’s encryption component content is filtered from the received client encryption component
  3. The server sends a Certificate packet. The message contains a public key certificate.
  4. Then, the server sends a Server Hello Done packet to notify the client that the INITIAL SSL handshake negotiation is complete
  5. After the SSL handshake is complete, the client uses the Client Key Exchange packet as the conference. The packet contains a random password string called pre-master secret, which is used in communication encryption
  6. Then the client sends a change cipher space packet. The packet prompts the server that the communication after the packet is encrypted with the pre-master secret key
  7. The client sent a Finished packet. Procedure The packet contains the overall checksum of all packets so far connected. Whether the handshake negotiation can succeed depends on whether the server can decrypt the packet correctly
  8. The server also sends a change cipher space packet
  9. The server also sent a FINISHED packet
  10. After exchanging finished packets between the server and client, the SSL connection is established and HTTP communication starts. All communication content is encrypted using pre-master Secret. Then start sending the HTTP request
  11. When the application layer receives an HTTP request, it sends an HTTP response
  12. Finally, a client disconnects

Why should asymmetric encryption be used for key transfer?

Asymmetric encryption is for the security of the pre-master secret key generated by the client. It can be seen from the above steps that the step of sending the public key certificate to the client may be intercepted. If symmetric encryption is used, when the client sends the pre-master secret key to the server, If it is intercepted by a hacker, it can be decrypted using the public key, leaving the pre-master secret secret unprotected

Two-way authentication understand?

The HTTPS communication process only verify the server’s identity, and the server did not verify the identity of the client, is a two-way authentication server will ensure that the identity of the client, the process is probably the client after checking the server’s certificate, will send your public key to the server, and then generate a new key is encrypted with the public key of a service, to the client, The client then decrypts it with the private key, which is then used for symmetrically encrypted communication

8: How to use Charles to capture HTTPS packet? What are the principles and processes?

Process:

  • Start by installing the Charles certificate on your phone
  • Enable SSL Proxying in proxy Settings
  • Then add the address of the server to be captured

Principle:

Charles acts as a middleman, masquerading as a server to the client and as a client to the server. In a nutshell:

  • Intercepts THE HTTPS request from the client and sends the REQUEST to the server disguised as a middleman client
  • The receiving server returns and sends the data content to the client disguised as a man-in-the-middle server with its own certificate.

9: What is a man-in-the-middle attack? How to avoid it?

  • A man-in-the-middle attack is a man-in-the-middle attack that intercepts client requests and server responses. For example, Charles captures HTTPS packets.
  • Avoid: The client can pre-bury the certificate locally and then compare the certificate to see if it is a match

10: What are the optimization strategies for App network layer?

  • Optimize DNS resolution and caching
  • Compress the transmitted data to reduce the transmitted data
  • Use caching to reduce the number of requests
  • Use strategies to reduce the number of times a request is initiated, such as not making a new request until the last one hits the ground
  • Avoid network jitter and provide retransmission mechanism

11: [self class] and [super class]

@implementation Son : Father
- (id)init
{
    self = [super init];
    if (self)
    {
        NSLog(@"%@", NSStringFromClass([self class]));
        NSLog(@"%@", NSStringFromClass([super class]));
    }
return self;
}
@end
Copy the code

Self versus super

  • Self is a hidden argument of the class, and the first argument of each method implementation is self
  • Super doesn’t hide arguments, it’s really just a ** “compiler identifier” ** that tells the compiler that when a method is called, call the parent class’s method, not its own
  • When calling [super Class], the Runtime will call objc_msgSendSuper instead of objc_msgSend
OBJC_EXPORT void objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ ) /// Specifies the superclass of an instance. struct objc_super { /// Specifies an instance of a class. __unsafe_unretained id receiver; /// Specifies the particular superclass of the instance to message. #if ! defined(__cplusplus) && ! __OBJC2__ /* For compatibility with old objc-runtime.h header */ __unsafe_unretained Class class; #else __unsafe_unretained Class super_class; #endif /* super_class is the first class to search */ }Copy the code

[super class] is a call to [super_class]. Objc_msgSendSuper should work like this:

  • Starting with the list of methods of the superClass parent that the objc_super structure points to,
  • Call the selector of the parent class with objc->receiver. Note that the last caller is objc->receiver, not super_class!

So objc_msgSendSuper is finally converted to

objc_msgSend(objc_super->receiver, @selector(class))
 
+ (Class)class {
    return self;
}
Copy the code

12: Property and attribute modifiers

The essence of @property is ivAR + setter + getter.

What happens internally each time we add an attribute:

1. Ivar_list adds a description of a member variable;

2. Add descriptions of setter and getter methods to method_list.

3. Add an attribute description to the attribute list.

4. Calculate the offset of the property in the object.

5. The corresponding implementation of setter and getter methods is given. In setter methods, the value is assigned from the offset position, and in getter methods, the value is assigned from the offset position.

Decorator:

Under MRC: assign, retain, Copy, Readwrite, Readonly, nonatomic, atomic, etc.

ARC: Assign, strong, weak, Copy, ReadWrite, ReadOnly, Nonatomic, Atomic, NonNULL, NULlable, NULl_Resettable, and _Null_unspecified.

Here are the explanations

Assign: For basic data types, without changing the reference count. If you modify objects (objects are freed manually in the heap, primitive data types are freed automatically in the stack system), you will result in wild Pointers that are not set to nil after the object is freed.

Retain: As with strong, the old object is released, and the reference count of the new object passed in is +1. It comes in pairs with release in MRC.

Strong: Used in ARC to tell the system to leave the object on the heap until there are no Pointers to it and ARC does not need to worry about reference counting.

Weak: Reserved as much as possible and does not change the reference count before being strongly referenced. Weak reference is a weak reference, you don’t own it; It essentially allocates an unheld property, and when the referrer is destroyed (dealloc), the weak reference pointer is automatically set to nil. Circular references can be avoided.

Copy: generally used to modify immutable type attribute fields, such as NSString, NSArray, and NSDictionary. The copy modifier protects this object from external influences. When an NSMutableString is assigned to an NSString, modifying the NSMutableString causes the value of the NSString to change. Blocks often use the copy modifier, but in ARC the compiler automatically copies the block, which has the same effect as strong. But in MRC, the block inside the method is in the stack, and you can use copy to put it in the heap.

Readwrite: read and write. The compiler automatically generates setter/getter methods.

Readonly: read-only. Tells the compiler not to automatically generate setter methods. Attribute cannot be assigned.

Nonatomic: Non-atomic access. Using nonatomic means that variables can be accessed by multiple threads, making the reader thread unsafe. But it improves execution performance.

-sheldon: Atomic access. The compiler automatically generates mutex locks for setter and getter methods to ensure thread-safe property assignment and atomicity operations, but not mutable property operations and access. For example, it is not atomic’s responsibility to add or remove objects from an array, so adding or removing objects from an atomic array is not thread-safe. The disadvantage of atomic access is that it can consume performance and result in slow execution.

Nonnull: Sets a property or method parameter that cannot be null, used specifically to modify Pointers, and cannot be used for basic data types.

Nullable: Setting property or method parameters can be null.

Null_resettable: Sets attributes. Get cannot return null. Set can be assigned to null.

_Null_unspecified: The attribute or method parameter is unspecified.

The last four attributes should mainly be used to improve the development specification, indicating what values should be passed by the user, and warning if the specification values are violated.

Weak is automatically set to nil when the weak object is released.

The Runtime maintains a weak table that stores all the weak Pointers to an object. The weak table is a hash table where Key is the address of the object and Value is the address array of the weak pointer (the address Value is the address of the object).

The implementation principle of weak can be summarized in three steps:

1. Initialization: The Runtime calls the objc_initWeak function and initializes a new weak pointer to the address of the object.

2. When adding a reference: the objc_initWeak function will call objc_storeWeak(), which updates the pointer pointer and creates the corresponding weak reference table.

3. When releasing, call the clearDeallocating function. The clearDeallocating function first fetches an array of weak pointer addresses based on the object’s address, then iterates through the array to set it to nil, deletes the entry from the Weak table, and clears the object’s record.

13: The difference between member variable IVar and property, and the role of different keywords

  • ** Member variables: The default modifiers for ** member variables are @protected. Set and GET methods are not generated automatically. They need to be implemented manually.

  • ** attributes: The ** attributes generate underlined member variables and setter/getter methods by default. They can be called using dot syntax, but actually call set and get methods.

Note: Attributes added to a category do not automatically generate setter/getter methods, they must be added manually.

** instance variable: the object instantiated by the **class is an instance object

Keyword function:

Access scope keyword

  • @public: Declare a public instance variable. You can access the object’s member variables directly from anywhere.

  • @private: Declares a private instance variable. It can only be accessed directly in the object method of the current class. To access it, subclasses need to call the get/set method of their parent class.

  • @protected: Can be accessed directly from the current class and its subclass object methods (system default).

  • @package: directly accessible under the same package, such as within the same framework.

The keyword

  • @property: Declare a property. Automatically generate a member variable _propertyName(modified with @private by default), declaration of property setter and getter methods, implementation of property setter and getter methods. ** Note: ** only declarations of getter and setter methods are generated in the @protocol, so you need to manually implement getter and setter methods as well as manually define variables.

  • Sythesize: Modify @property automatically generated _propertyName member variable name, @synthesize propertyName = newName; .

  • @dynamic: tells the compiler that setter and getter methods for a property are implemented by the user and not automatically generated. ** Use caution: ** If you assign a value to a property, it will compile successfully, but if you run it, the program will crash. This is often referred to as dynamic binding.

  • @interface: declaration class

  • @implementation: Implementation of a class

  • @selecter: Create an SEL, class member pointer

  • @protocol: indicates the declaration protocol

  • Autoreleasepool: Automatic releasepool in ARC

  • @end: end of the class

14:runloop

  • Runloop: An object for event/message management through a loop maintained internally by the system. Runloop is actually a do… A while loop, which starts when there are tasks and sleeps when there are no tasks.

  • The essence is to receive and send messages via the mach_msg() function.

RunLoop’s relation to threads:

  • RunLoop is used to manage threads. When a thread’s RunLoop is enabled, the thread will hibernate after executing the task and wait for new tasks.
  • Only runloops for the main thread are enabled by default. Runloops for other threads need to be enabled manually. So when the program starts, the main thread will always run, never exit.

Runloop Internal flow of the event loop mechanism

RunLoop involves five classes:

  • CFRunLoop: RunLoop object,

  • CFRunLoopMode: five RunLoop modes

  • CFRunLoopSource: Input source/event source, including Source0 and Source1

  • CFRunLoopTimer: timing source, NSTimer,

  • CFRunLoopObserver: An observer that listens for runloops.

CFRunLoop: RunLoop object

CFRunLoopMode: indicates the RunLoop operation mode. There are five types:

  1. KCFRunLoopDefaultMode: The default Mode in which the main thread is normally run.
  2. UITrackingRunLoopMode: interface tracing Mode, used by ScrollView to track touch sliding, ensuring that the interface sliding is not affected by other modes.
  3. UIInitializationRunLoopMode: in the first to enter the first Mode when just start the App, start after the completion of the will no longer be used.
  4. GSEventReceiveRunLoopMode: accept system internal Mode of events, usually in less than.
  5. KCFRunLoopCommonModes: this is a pseudo-mode that can be run in a mode marked CommonModes and the RunLoop will automatically change it

The Source, Observer, and Timer in _commonModeItems are synchronized to the Mode with this flag.

CFRunLoopSource: input source/event source, including Source0 and Source1:

  1. Source1: Processes events from the system kernel or other processes, such as clicking on the phone screen, based on mach_Port.
  2. Source0: Non-port-based processing events, i.e., application layer events, need to be manually marked as pending and manually wake up RunLoop.

Simple example: An APP is still in the foreground, and the user clicks the APP interface. The Event on the screen surface will be wrapped as an Event and told to Source1 (mach_port). Source1 will wake up RunLoop and distribute the Event to Source0, which will process it.

CFRunLoopTimer: timing source, NSTimer. Wake up RunLoop at a preset point in time to perform a callback. Since it is runloop-based, it is not real-time (i.e. NSTimer is inaccurate). Because RunLoop is only responsible for distributing messages from the source. If the thread is currently working on a heavy task, the Timer may be delayed or executed less than once.

CFRunLoopObserver: An observer that listens to the following points in time: CFRunLoopActivity

  • KCFRunLoopEntry: RunLoop ready to start

  • KCFRunLoopBeforeTimers: RunLoop will handle some timer-related events

  • KCFRunLoopBeforeSources: RunLoop will handle some Source events

  • KCFRunLoopBeforeWaiting: RunLoop is going to sleep, it is going to switch from user state to kernel state

  • KCFRunLoopAfterWaiting: The RunLoop is awakened after switching from the kernel state to the user state

  • KCFRunLoopExit: RunLoop exits

  • KCFRunLoopAllActivities: Listens for all states

Connections between data structures:

1: Runloop has a one-to-one relationship with threads

2: Runloop and RunloopMode are one-to-many

3: RunloopMode and RunloopSource are one-to-many

4: RunloopMode and RunloopTimer are one-to-many

5: RunloopMode and RunloopObserver are one-to-many

Why is main able to persist and never exit?

UIApplicationMain is called inside the main function, and the main thread runloop is launched inside the UIApplicationMain function, so that when there is a message processing, it can quickly switch from the kernel state to the user state, and immediately wake up processing. When there is no message processing, switch from user mode to kernel mode to enter the waiting state to avoid resource occupation. So main can always exist without exiting.

// // internal RunLoop execution process c // SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled) { /* DOES CALLOUT */ CHECK_FOR_FORK(); if (__CFRunLoopIsDeallocating(rl)) return kCFRunLoopRunFinished; __CFRunLoopLock(rl); CurrentMode = __CFRunLoopFindMode(rl, modeName, false); /// Notify Observers: RunLoop is about to enter loop. __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopEntry); / / / internal function, into the loop result = __CFRunLoopRun (rl, currentMode, seconds, returnAfterSourceHandled, previousMode); /// Notify Observers: RunLoop is about to exit. __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit); return result; } static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef RLM, CFTimeInterval seconds, Boolean stopAfterHandle, CFRunLoopModeRef previousMode) { int32_t retVal = 0; Do {/// notify Observers: about to handle the timer event __CFRunLoopDoObservers(RL, RLM, kCFRunLoopBeforeTimers); / / / notify Observers: __CFRunLoopDoObservers(rl, RLM, kCFRunLoopBeforeSources); Boolean sourceHandledThisLoop = __CFRunLoopDoSources0(rl, RLM, stopAfterHandle); __CFRunLoopDoBlocks(rl, RLM); If (__CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), &livePort, 0, &voucherState, NULL)) {/// handle message goto handle_msg; } /// Notify Observers: about to enter hibernation __CFRunLoopDoObservers(rl, RLM, kCFRunLoopBeforeWaiting); __CFRunLoopSetSleeping(rl); __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll? 0 : TIMEOUT_INFINITY, &voucherState, &voucherCopy); // user callouts now OK again __CFRunLoopUnsetSleeping(rl); /// notify Observers: astounded, ending dormancy __CFRunLoopDoObservers(rl, RLM, kCFRunLoopAfterWaiting); Handle_msg: if (awakened by Timer) {// Handle Timers __CFRunLoopDoTimers(rl, RLM, mach_absolute_time()); } else if (GCD wake up) {/// handle GCD __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(MSG); } else if (by Source1) {/// by Source1, Source1 __CFRunLoopDoSource1(rl, RLM, RLS, MSG, MSG ->msgh_size, &reply)} // Handle block __CFRunLoopDoBlocks(rl, RLM); if (sourceHandledThisLoop && stopAfterHandle) { retVal = kCFRunLoopRunHandledSource; } else if (timeout_context->termTSR < mach_absolute_time()) { retVal = kCFRunLoopRunTimedOut; } else if (__CFRunLoopIsStopped(rl)) { __CFRunLoopUnsetStopped(rl); retVal = kCFRunLoopRunStopped; } else if (rlm->_stopped) { rlm->_stopped = false; retVal = kCFRunLoopRunStopped; } else if (__CFRunLoopModeIsEmpty(rl, rlm, previousMode)) { retVal = kCFRunLoopRunFinished; } } while (0 == retVal); return retVal; } // main dispatch queue __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ // __CFRunLoopDoObservers __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ // __CFRunLoopDoBlocks __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ // __CFRunLoopDoSources0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ // __CFRunLoopDoSource1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ // __CFRunLoopDoTimers __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__Copy the code

15:runtime

What is Runtime?

Runtime A set of APIS written in C, C ++, and assembly to provide runtime functionality for OC. The ability to defer the determination of data types from compile time to runtime.

Question 1: the nature of the method, question 2: the messaging mechanism of the Runtime

The essence of a method is to send a message. Main process of sending messages:

  • Quick lookup: objc_msgSend finds cache_T cache messages
  • Slow lookup: Recursive self and parent lookup method lookUpImpOrForward
  • Unable to find message, dynamic method resolution: resolveInstanceMethod
  • News fast forwarding: forwardingTargetForSelector
  • Message slowly forward: signature methodSignatureForSelector and distribute forwardInvocation
  • Unrecognized selector sent to instance XXX

The CLS passed in is no longer a class, but a metaclass. You can get the metaclass of the class through the objc_getMetaClass method, because the class methods are instance methods in the metaclass

What is SEL? What is IMP? What’s the connection?

  • SEL is the method number, or method name, that was loaded into the table in memory by the read_image method when dyLD loaded the image.
  • IMP is a function to achieve the pointer, looking for IMP is looking for the process of the function

The relationship between the two: SEL is equivalent to the title of the book’s table of contents, IMP is the page number of the book. To find a specific function is to read a specific chapter in the book:

1). We first know what we want to see, that is, title-sel

2). Then follow the directory corresponding page number – IMP

3). Open the concrete content – the concrete implementation of the method

The runtime application:

1. Method exchange: the interception system’s own Method call (Method Swizzling black magic) is applied specifically.

2. Implementation adds attributes to the classification

3. Realize dictionary model and automatic conversion

4.JSPatch to replace the existing OC method, etc

5. Aspect programming

Can I add instance variables to the compiled class? Can I add instance variables to classes created at run time? Why is that?

1. You cannot add instance variables to compiled classes. 2. You can add instance variables to classes created at run time. 3. Because the compiled class is registered with the Runtime, the linked list of objc_iVAR_list instance variables and the memory size of instance_size instance variables in the class structure have been determined. At the same time, the Runtime calls class_setIvarLayout or class_setWeakIvarLayout to handle strong and weak references, so you cannot add instance variables to existing classes. Classes created at run time can add instance variables and call the class_addIvar function. But after calling objc_allocateClassPair, before objc_registerClassPair, for the same reason.

16: Add the distinction between attributes and member variables to the Category

The main purpose of a Category is to dynamically add methods to a class without changing the existing class. The structure pointer to the classification has no property list, only method list. In principle, it can only add methods, not properties (member variables), But you can use the runtime association object objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC); , objc_getAssociatedObject (self, @ the selector (name)); .

  • Classes can write @property, but they don’t generate setter/getter declarations and implementations, and they don’t generate private member variables. They compile, but references to variables report errors.
  • If there is a method with the same name as the original class in the classification, the method in the classification will be called first, that is to say, the method of the original class will be ignored. The priority of the method invocation is the parent class of the classification, because the method is placed in the method stack, following the principle of first in, last out.

17: isa pointer

  • Isa is an 8-byte (64-bit) pointer to a Class object. Isa is an 8-byte (64-bit) pointer to a Class object.
  • Each instance object has a pointer to ISA to the object’s class. Class also has a pointer to isa to a meteClass. Metaclasses hold a list of class methods. When a class method is called, the metaclass looks for its implementation from itself. If not, the metaclass looks for the method from its parent. MeteClass is also a class, which is also an object and has isa Pointers.
  • The isa of the object points to the class, the ISA of the class points to the meta class, the metaclass ISA points to the root metaclass, and the ISA of the root metaclass points to itself, forming a closed inner loop. Isa can help an object find its method.
  • Isa points to the inheritance relation of the class in the diagram: Teacher -> Person -> NSObject -> nil. The thing to notice here is that the parent of the root metaclass is NSObject, and the parent of NSObject is nil.

18:block

What is a Block A Block is an object that encapsulates a function and its execution context.

What is a Block call a Block call is a function call.

Several forms (types) of blocks

Blocks come in three forms, including:

  • GlobalBlock (_NSConcreteGlobalBlock) : When we declare a Block, if the Block does not capture external variables, then the Block is in the global (initialized data (.data) area).

  • Stack Block (_NSConcreteStackBlock) :

  • In ARC, when we declare and define a block, the __strong modifier is used by default. If the block captures an external variable, it is essentially a transition from __NSStackBlock__ to __NSMallocBlock__. It’s just that the system has done the copy operation for us, moving blocks from the stack to the heap, extending the life cycle of blocks. For stack blocks, variable scope ends and space is reclaimed.

  • Across ARC, if a block is declared __weak or __unsafe__unretained, the system will not copy it and will not migrate it to the heap.

  • Heap Block (_NSConcreteMallocBlock) :

  • 1). In the MRC environment, we need to manually call the copy method to migrate blocks to the heap

  • 2). In ARC environments, __strong (the default) blocks capture external variables in the heap, NSMallocBlock supports retain, release, and reference count +1 or -1.

Only local variables – and defined properties are copied to the heap

  • 1). Stored in the data area of the program, no external variables are referenced inside the block.

  • 2). Blocks that use external variables and do not copy are stack blocks.

  • 3). Copy stack blocks, that is, heap blocks. Copying a heap Block increases the reference count. Copy a global block, still a global block.

When should __block modifiers be used?

  • 1). Assigning to intercepted variables requires adding a __block modifier (assign! = use).

  • 2). Assignments to local variables (primitive data types and object types) require the __block modifier. Internally, it copies the __block object, so it can change the value of the intercepted variable without interfering with the external variable.

  • 3). Static local variables, global variables, static global variables do not need __block modifier.

Intercept variable properties of blocks?

  • A local variable Block of a primitive data type can intercept its value.
  • Local variables for object types are intercepted along with the ownership modifier.
  • Local static variables are intercepted as Pointers.
  • Blocks do not intercept global variables and static global variables.

Weak Breaks the Block loop reference principle

  • The internal operation of block is the pointer address of weakSelf, which is two different pointer addresses with self, that is, there is no direct holding of self, so weakSelf can break the cycle reference relation of self self-block-WeakSelf.

19: Sorting algorithm

The three sorting algorithms of selection sort, bubble sort and insert sort can be summarized as follows: they divide the array into sorted parts and unsorted parts. 1. Select sort defines the sorted part at the left end, and then selects the smallest element of the unsorted part to swap with the first element of the unsorted part. 2. Bubble sort defines the sorted part at the right end, and swaps the largest element to the right end while traversing the unsorted part. 3. Insert sort defines the sorted part at the left end, and inserts the first element of the unsorted part into the appropriate position of the sorted part.

19.1. Selection sorting

  • [Selection sort] : the highest value appears at the beginning
  • First run: find the smallest (largest) number in n number swap position with the first number
  • Step 2: Find the smallest (largest) number in the remaining n-1 number to swap with the second number
  • Repeat this operation… And the third, and the fourth… Number switching position
  • The ascending (descending) order of data can be finally realized at the n-1 pass.

19.2. Bubble Sort

  • [Bubble sort] : compare adjacent elements in pairs, compare once, and the maximum value appears at the end
  • First run: compare the two adjacent numbers in turn, continuously exchange (before decimal, after large number) one by one, the most value finally appears in the NTH element position
  • The second step: compare the two adjacent numbers in turn, continuously exchange (before decimal, after large number) advance one by one, the most value finally appears in the n-1 element position
  • … …
  • N-1: compare the two adjacent numbers in turn, continuously exchange (before decimal, after large number) advance one by one, the most value finally appears in the second element position

20: Split search (binary search)

Split search: optimize search time (without traversing all data)

  • The array must be ordered
  • Min and Max must be known (know the range)
  • Dynamically calculate the value of mid and take out the corresponding value of MID for comparison
  • If the value of mid is greater than the value you are looking for, Max is reduced to mid-1
  • If the value of mid is less than the value you are looking for, then min is increased to mid+1

Encapsulation, inheritance and polymorphism are three characteristics of object orientation:

  • Package: There are various circuit boards and electronic components in the TV set in our home. These circuit boards and components are installed in the shell of the TV, which is equivalent to being packaged and provided with a switch button. We can turn on the TV by pressing the button. Instead of allowing us to manipulate the inside of the TV set, the manufacturer provides us with an on/off button that allows us to manipulate the inside of the TV case.This is packaging.

  • Inheritance: Inheritance in programs is different from inheritance in our lives. Inheritance in programs means that a class inherits from another class and has all the non-private properties and methods of that class. You can call them as if they were your own properties and methods. The inherited class is called a superclass, and the classes that inherit from the superclass are called subclasses.

  • Polymorphism: Polymorphism refers to an object can reflect a variety of forms, such as the cat inherited from the animal, then the cat can reflect two forms, one is a cat, one is an animal. In code, this usually means assigning a subclass object to a superclass type, overriding the methods in the subclass, and executing the methods in the subclass. Here, when a variable of a superclass type is assigned to a different subclass type, methods of objects of different subclasses are called, so polymorphism can also be interpreted as producing different results for the same method call.

22: Huffman tree

Huffman tree is a binary tree with the minimum weight path length when the leaf nodes and weights are determined, also known as the optimal binary tree.

  • Path: A path from one node to another in a tree
  • Path length: In a path, the path length increases by 1 each time it passes through a node
  • Node weight: Assign a new value to each node, called the node weight
  • The weighted path length of a node: the product of the weight of the node and the length of the path from the node to the node
  • The weighted path length of the tree is the sum of the weighted path length of all leaf nodes in the tree. Usually referred to as “WPL”
  • When attempting to construct a tree with n nodes (all leaf nodes and each with its own weight), the tree is called an “optimal binary tree”, sometimes also called a “Huffman tree” or “Huffman tree”, if the tree constructed has the minimum weight path length.

In principle, we should keep leaves with less weight away from the roots and leaves with more weight close to the roots

23: weak principle

The Runtime maintains a weak table that stores all Pointers to an object. The weak table is a hash table where key is the address of the object and value is an array of Pointers to the weak object. Weak Implementation steps:

  1. Initialization: The Runtime calls the objc_init_weak function and initializes a new weak pointer to the address of the object.
  2. When adding a reference: the objc_init_weak function will call the objc_storeWeak function. The objc_storeWeak function will update the pointer pointer and create the corresponding weak reference table.
  3. The ClearDealLocating function is called when you release. The ClearDealLocating function first fetches an array of weak pointer addresses based on the object’s address, then iterates over the array to make it nil, and finally deletes the entry from the Weak table, cleaning up the object’s record.

24: How does iOS implement KVO for an object? (What is the nature of KVO?)

  • Use the RuntimeAPI to dynamically generate a subclass and have the Instance object’s ISA point to the new subclass
  • When modifying the properties of an instance object, Foundation’s _NSSetXXXValueAndNotify function is called, which internally calls the following methods
  • willChangeValueForKey:
  • The original setter of the parent class
  • didChangeValueForKey:
  • Internal will trigger the listener (Oberser) surveillance methods (observeValueForKeyPath: ofObject: change: context:)

How to trigger KVO manually?

  • Manually call willChangeValueForKey and didChangeValueForKey:

Does directly modifying a member variable trigger KVO?

  • KVO is not triggered because it overrides the set method internally to reach the listener