Principle 3 :(multithreading, memory management)

12. The Runtime

12.1 introduce the runtime

Objective-c is a very dynamic programming language, which is very different from C, C++ and other languages. The dynamic nature of Objective-C is supported by the Runtime API. The Runtime API provides interfaces in C, and the source code is written in C++ assembly languageCopy the code

12.2 the isa,

Before the ARM64 architecture, ISA was a common pointer, storing the memory address of the Class and meta-class objects. Starting with the ARM64 architecture, ISA was optimized to become a common (union) structure, and bit fields were used to store more informationCopy the code

12.3 ISA – Bit domain

12.4& (Bitwise and Symbol Introduction)

&1 = 1, 1 = 0 0000&0010 can fetch a specific bit value mask: When 1<<0 moves 0 bits to the left, it is 0b 0000 0001 1<<1 moves 1 bit to the left, it is 0b 0000 0010 1<<2 moves 2 bits to the left, it is 0b 0000 0400 1 moves several bits to the leftCopy the code

12.5 | (bitwise or)

| 1 is 1, 1, 0 is 1, 2, 0 0000 | 0010 result is 0010Copy the code

12.6 ~(Reversed by Bit)

~ 0000 1010 is the inverse of 1111 0101Copy the code

12.7 a domain

struct{ char tall : 1; Char rich: 1; char handsome: 1 }test   // 0b0000 0111

Copy the code

12.8 the appropriate

unioc{
  char bits;
  
  struct{
    char tall : 1; 
    char rich : 1;
    char handsome: 1
   } test    

}
Copy the code

12.9 Class Structure

12.10 class_rw_t

12.11 class_ro_t

12.12 method_t

12.13 Method Caching

The Class internal structure has a method cache (cache_t), which uses hash tables (hash tables) to cache previously called methods to speed up method lookupsCopy the code

Objc -cache.mm bucket_t * cache_t::find(cache_key_t k, id receiver)Copy the code

12.14 Runtime objc_msgSend() Message mechanism

Objc_msgSend (object,sel_registerName(method name string)) // Message receiver (receiver) // message name // OC method call: message mechanism, sending messages to the method caller Internal execution is divided into 3 phases 1. Message sending 2. Dynamic method resolution 3. Message forwardingCopy the code

12.15 Message Sending Process

1. Search the class object method cache by method name. If there is a method, return method address 2. If there is no cache, the method list is iterated for 3. The method returned is found and added to cache list 4. If you don't find it, you look it up in the parent cache, you look it up in the list of methods that go to the parent class, and you look it up in the parent classCopy the code

12.16 Dynamic Method Parsing

If the message is sent and no method is found, dynamic method resolution is performed. 2. If it is an object method call, _class_resoveInstanceMethod() is called. 3.+(BOOL)ResoveInstanceMethod:(SEL) SEL {class_getInstanceMethod(self,@selector(test)); Class_addMethod (self, @selecetor)test),
                  method_getImplementation(method),
                  method_getTypeEndcoing(method));
                  
   returnYES; } class methods do the sameCopy the code

Dynamic addition method

12.17 Message Forwarding

/ / message forwarding - (id) forwardTargetForSelector aSelector: (SEL) {/ / judgment method nameif(aSelector == @selector(test){// forward to which object to resolvereturn[NSPerson alloc]init]; }} / / message forwarding - method signatures, the return value type and parameter types - (NSMethodSignature *) methodSignatureForSelector aSelector: (SEL) {if(aSelector == @selector(testMethod))
    {
        return [NSMethodSignature signatureWithObjCTypes:"v@:"];
    }
    return nil;
}
 
 
-(void)forwardInvocation:(NSInvocation *)anInvocation
{
    if (anInvocation.selector == @selector(testMethod)) { TestModelHelper1 *h1 = [[TestModelHelper1 alloc] init]; TestModelHelper2 *h2 = [[TestModelHelper2 alloc] init]; [anInvocation invokeWithTarget:h1]; [anInvocation invokeWithTarget:h2]; }}Copy the code

[self class] & [super Class]

[super message] The message receiver is still a subclass, the method lookup is a super call from the parent class, which is converted to an objc_msgSendSuper2 function call, receiving two arguments struct objc_super2 SELCopy the code

Receiver is the message receiver current_class is the Class object of receiverCopy the code

12.19 Application of Runtime 01 – Viewing Private Member Variables

12.20 Applications of Runtime 02 — Dictionary to model

Use Runtime to iterate through all attributes or member variables using KVCCopy the code

12.21 Switching Runtime Methods

class_replaceMethod
method_exchangeImplementations

Copy the code

12.22. Commonly used API

12.22.1 Runtime API01 — Class

Create a class dynamically (parameter: Parent class, class name, Extra memory space) Class objc_allocateClassPair(Class superclass, const char *name, Void objc_registerClassPair(Class CLS) Destroy a Class void objc_disposeClassPair(Class) Class object_getClass(id obj); CLS; Class CLS) Determines whether an OC object is aClass BOOL object_isClass(ID obj) Determines whether aClass is a metaclass. BOOL class_isMetaClass(Class CLS) Retrieves the parent Class class_getSuperclass(Class cls)Copy the code

12.22.2 Runtime API02 — Member variables

Ivar class_getInstanceVariable(Class CLS, Const char *name) Ivar *class_copyIvarList(Class CLS, Void object_setIvar(id obj, Ivar Ivar, id value) id object_getIvar(id obj, BOOL class_addIvar(Class CLS, const char * name, size_t size, BOOL class_addIvar(Class CLS, const char * name, size_t size, uint8_t alignment, Const char * types) Obtain information about member variables const char *ivar_getName(Ivar v) const char *ivar_getTypeEncoding(Ivar v)Copy the code

12.22.3 Runtime API03 — Properties

Get a property objc_property_t class_getProperty(Class CLS, Const char *name) copy property list (free) objc_property_t *class_copyPropertyList(Class CLS, Unsigned int *outCount) BOOL class_addProperty(Class CLS, const char *name, Const objc_property_attribute_t *attributes, unsigned int attributeCount) void class_replaceProperty(Class CLS, const char *name, const objc_property_attribute_t *attributes, Unsigned int attributeCount) gets some information about an attribute const char *property_getName(objC_property_t property) const char *property_getAttributes(objc_property_t property)Copy the code

####12.22.4 Runtime API04 — Method

Method class_getInstanceMethod(CLS, SEL name) Method class_getInstanceMethod(CLS, SEL name) IMP class_getMethodImplementation(Class CLS, SEL name) IMP class_getMethodImplementation(Method m, IMP imp) void method_exchangeImplementations(Method m1, Method *class_copyMethodList(Class CLS, Unsigned int *outCount) BOOL class_addMethod(Class CLS, SEL name, IMP IMP, Const char *types) IMP class_replaceMethod(Class CLS, SEL name, IMP IMP, SEL method_getName(Method m) IMP method_getImplementation(Method m) SEL method_getName(Method m) IMP method_getImplementation(Method m) const char *method_getTypeEncoding(Method m) unsigned int method_getNumberOfArguments(Method m) char *method_copyReturnType(Method m) char *method_copyArgumentType(Method m, Unsigned int index) selector associated const char *sel_getName(SEL SEL) SEL sel_registerName(const char * STR) implement IMP with block as method imp_implementationWithBlock(id block) id imp_getBlock(IMP anImp) BOOL imp_removeBlock(IMP anImp)Copy the code

13. The runloop

13.1 runloop profile

Run loop – To loop to do something while the program is running

Application category Timer, PerformSelector GCD Async Main Queue event response, gesture recognition, interface refresh network request AutoreleasePoolCopy the code

13.2 Basic Functions of Runloop

The basic function of RunLoop is to keep the application running continuously. Handle various events in the App (such as touch events, timer events, etc.) to save CPU resources and improve application performance: Do things when you should, rest when you should......Copy the code

13.3 the Runloop object

There are two apis in iOS to access and use RunLoop Foundation: NSRunLoop Core Foundation: CFRunLoopRef NSRunLoop and CFRunLoopRef both represent RunLoop objects. NSRunLoop is a layer of OC wrapper based on CFRunLoopRef. CFRunLoopRef is open source https://opensource.apple.com/tarballs/CF/Copy the code

13.4 Relationship between Runloops and threads

Each thread has a unique RunLoop object that is stored in a global Dictionary, thread as key, and RunLoop as value. When the thread is created, it doesn't have a RunLoop object. The RunLoop of the main thread is automatically acquired (created), and the child thread has no RunLoop enabled by defaultCopy the code

13.5 Obtaining a RunLoop Object

Foundation [NSRunLoop currentRunLoop]; // Get the current thread's RunLoop object [NSRunLoop mainRunLoop]; // Get the main thread RunLoop object Core Foundation CFRunLoopGetCurrent(); // Get the current thread's RunLoop object CFRunLoopGetMain(); // Get the main thread RunLoop objectCopy the code

13.6 Runloop-related Classes

13.7 CFRunloopModeRef mode

The mode of the representative CFRunLoopModeRef RunLoop A RunLoop contains several Mode, each Mode and contains several Source0 / Source1 / Timer/Observer RunLoop startup can only choose one of the Mode, As currentMode if need to switch Mode, only out of the current Loop, choose a Mode again into different groups of Source0 / Source1 / Timer/Observer can be separated, Each other If there is no any Source0 / Source1 / Timer Mode/Observer, RunLoop immediately exitCopy the code
KCFRunLoopDefaultMode (NSDefaultRunLoopMode) : the default Mode of the App, usually the main thread is run in this Mode UITrackingRunLoopMode: Interface tracking Mode, used for ScrollView tracking touch sliding, to ensure that the interface sliding is not affected by other modesCopy the code

Add an Observer to listen for all RunLoop states

13.8 Running Logic

13.9 Application of RunLoop in Practice

Control thread life cycle (thread survival) solves the problem that NSTimer stops working when sliding. Monitoring application Caton performance optimizationCopy the code

13.10 Thread Survival (Resident Thread)

Runloop if there is nothingsource/source0 timer/ Observer will exitCopy the code

Reference: iOS Basic Principles class (part 2) /OC object/Associated object/multi-threading/memory management/performance optimization