A practical summary of the runtime for iOS development notes

Source: Internet
Author: User
Tags list of attributes

Objective


Runtime information online There are many, some obscure difficult to understand, I through their own learning methods summed up, mainly talk about some common methods of function, to practical, I think the impression is the most profound.
There is also a lot of runtime knowledge, want to learn more about the official documents can be translated (a bit boring)

What is runtime?


Runtime is a set of C-language APIs (introduced <objc/runtime.h> or <objc/message.h>) at the base of OC, which eventually translates the OC code into run-time code, compiled with terminal commands. m File: CLANG-REWRITE-OBJC XXX.M can see the compiled xxx.cpp (c + + file).
For example, we created an object [[NSObject Alloc]init], eventually converted to tens of thousands of lines of code, the most critical sentence can be seen from the bottom is the object created by the runtime, OC Everything is designed to be objects, we all know that a class is initialized to an instance, This instance is an object. In fact, a class is essentially an object that is represented in the runtime with a struct. As follows:

//The representation of a class in runtimestructObjc_class {class Isa;//pointers, as the name implies, represent what is,//an instance of Isa points to a class object, and the class object's Isa points to the Meta class#if!__objc2__Class Super_class; //point to Parent class    Const Char*name;//class name    Longversion; Longinfo; Longinstance_sizestructObjc_ivar_list *ivars//List of member variables    structObjc_method_list **methodlists;//Method List    structObjc_cache *cache;//Cache//an optimization, the called method is stored in the cache list, the next call first look for the cache    structObjc_protocol_list *protocols//Protocol List    #endif} objc2_unavailable;/*Use ' Class ' instead of ' struct objc_class * '*/

. cpp Files
Remove some of the cast statements, you can see the call method is the essence of the message, [[NSObject Alloc]init] statement sent two messages, the first time a alloc message, the second time to send the INIT message. Using this function we can explore the underlying, such as the implementation of the block principle.
Note that you need to import the header file using the Objc_msgsend () Sel_registername () method <objc/message.h>

Message mechanism

In addition, the runtime can do some functions that OC is not easy to implement

Implementation of two methods for dynamic switching (especially the method of the switching system)
Dynamically adding member variables and member methods for an object
Get all member methods of a class, all member variables


How do I apply run time?
1. Convert some OC code into runtime code to explore the underlying, such as the implementation of block;
2. Interception system comes with the method call (Swizzle black magic), such as interception imagenamed:, Viewdidload, alloc;
3. The implementation of the classification can also add attributes;
4. Realization of nscoding automatic archiving and automatic solution;
5. Implement automatic conversion of dictionaries and models.


Method a simple Exchange

Create a person class that implements the following two class methods in the class and declares them in the. h file

+ (void) eat{    NSLog (@ " eat ");} + (void) study {    NSLog (@ " learning ");}

The controller is called, then Print eat, after printing learning

[Person run];
[Person study];

The following method is implemented by the runtime to Exchange, class method with Class_getclassmethod, object method with Class_getinstancemethod

// get class methods for two classes class  class], @selector (study)); // Start Exchange Method implementation Method_exchangeimplementations (M1, M2); // after exchanging, print the study first, then print run!  [Person run];[ Person study];

You can see that the output is 2 exchanged information.

Get list

Sometimes there is the need to know the name of each property in the current class (such as the dictionary to model, the dictionary key and the Model object's property name do not match).
We can get some information about the class through the runtime's series of methods (including the list of attributes, the list of methods, the list of member variables, and the list of protocols to follow).

Unsignedintcount; //Get Property Listobjc_property_t *propertylist = Class_copypropertylist ([selfclass], &count);  for(unsignedintI=0; i<count; i++) {        Const Char*propertyname =Property_getname (Propertylist[i]); NSLog (@"Property ---->%@", [NSString stringwithutf8string:propertyname]); }    //get a list of methodsMethod *methodlist = Class_copymethodlist ([selfclass], &count);  for(unsignedintI i<count; i++) {Method method=Methodlist[i]; NSLog (@"method---->%@", Nsstringfromselector (Method_getname (method))); }    //get a list of member variablesIvar *ivarlist = Class_copyivarlist ([selfclass], &count);  for(unsignedintI i<count; i++) {Ivar Myivar=Ivarlist[i]; Const Char*ivarname =Ivar_getname (Myivar); NSLog (@"Ivar---->%@", [NSString stringwithutf8string:ivarname]); }    //get a list of protocols__unsafe_unretained Protocol **protocollist = Class_copyprotocollist ([selfclass], &count);  for(unsignedintI i<count; i++) {Protocol*myprotocal =Protocollist[i]; Const Char*protocolname =Protocol_getname (myprotocal); NSLog (@"protocol---->%@", [NSString stringwithutf8string:protocolname]); }

Looking at the output on Xcode, you need to write several properties, member variables, methods, and protocols to your current class, otherwise the list you get is nothing.

Method invocation

Let's take a look at the process of invoking the method at run time.

If an instance method is invoked with an instance object, the instance's Isa pointer points to the object (that is, the class object) operation.
If a class method is called, it is manipulated in the object that the ISA pointer to the class object points to (that is, the meta-class object).

    1. First, the method to invoke is found in the list of cached methods in the corresponding action object, and if found, turn to the corresponding implementation and execution.
    2. If not found, find the method in the method list in the corresponding action object, and if found, turn to the corresponding implementation
    3. If not found, go to the object that the parent pointer points to.
    4. And so on, if the root class hasn't been found yet, turn to intercept call.
    5. If there is no way to rewrite the interception call, the program error.

The above process brings me the inspiration:

    • Overriding the method of the parent class does not overwrite the parent class, except that the method is found in the current class object and will not be found in the parent class.
    • If you want to invoke the implementation of the parent class of a method that has already been overridden, simply use super this compiler identifier, which skips the process of looking for a method in the current class object at run time.

Intercept calls

As mentioned in the method call, if the method is not found, it will turn to intercept call.
So what is an interception call?
The interception call is that you have the opportunity to NSObject handle the four methods of rewriting before the calling method program crashes.

+ (BOOL) Resolveclassmethod: (SEL) sel; + (BOOL) Resolveinstancemethod: (SEL) sel; // the latter two methods need to be forwarded to the other class handling -(ID) forwardingtargetforselector: (SEL) aselector; -(void) Forwardinvocation: (nsinvocation *) aninvocation;
    • The first method is to call this method when you call a non-existent class method, by default return no, you can add your own processing and then return yes.
    • The second method is similar to the first method, except that the instance method is handled.
    • The third method is to redirect the non-existent method that you call to a class that declares the method, and you only need to return a target with this method.
    • The fourth method is to package the non-existent methods you call to NSInvocation pass to you. After you have done your own processing, call invokeWithTarget: the method to let a target trigger this method.

Dynamic Add method

Overriding the method of intercepting calls and returning yes, what are we going to do with it?
One way to do this is to SEL add a method dynamically based on the type of selector that is passed in.

First, implicitly calling a nonexistent method from the outside:

/ implicit call method [target Performselector: @selector (resolveadd:) Withobject:@ "111"];

The method of intercepting calls is then overridden inside the target object, adding methods dynamically.

voidRunaddmethod (IDSelf, SEL _cmd, NSString *string) {NSLog (@"Add C IMP",string);}+(BOOL) Resolveinstancemethod: (SEL) sel{//Add a method to this class dynamically    if([Nsstringfromselector (SEL) isequaltostring:@"Resolveadd:"]) {Class_addmethod (self, SEL, (IMP) Runaddmethod,"[email protected]:*"); }    returnYES;}

class_addMethodThe four parameters are:

The class CLS adds a method to which classes, in this case the  method Selfsel name adds, in this case the selector that is passed in by the overriding interception call. The implementation of IMP Imp  method can be obtained directly by means of C method. If it is OC method, you can use + (IMP) Instancemethodforselector: (SEL) Aselector; Get the implementation of the method. [Email protected]:* The signature of the   method, which represents a method that has a parameter.

  

Set properties in the category, set properties for any one object

As we all know, the classification is unable to set the property, if the classification of the declaration of @property can only generate the get and set method declaration, but unable to generate member variables, even though the point syntax can be called out, but the program will be crash after execution, some people will think of using global variables? such as this:

int _age;-(int) Age {    return _age;} -(void) Setage: (int) Age {    _age = age;}

But there is only one copy of the global variables program throughout the execution, and when we create multiple objects, modifying their property values modifies the same variable, so that each object has its own property value as if it were a property. At this point, we need to use the runtime to add attributes to the classification function.

The set method, which associates the value values with the object objects (storing value values in object objects)
Argument object: Which object to set the property parameter key: a property corresponding to a key, in the future can be removed by key the stored value, key can be any type: double, int, etc., we suggest char can save byte parameter value: Value parameter set for attribute policy: Storage Policy (assign, copy, retain is strong)

There are several associated policies:

enum {    0,    1,     3,    01401 ,     01403  };

Correlation Step : First in. h @property declare get and set method, convenient point syntax call;

@property (nonatomic,copy) NSString *name;

Override the set and get methods in. m, and internally use runtime to assign and take values to the attributes

Char Namekey; -(void) SetName: (NSString *) name {    // A value is associated with an object and a value is stored in an object    objc_ Setassociatedobject (self, &Namekey, name, objc_association_copy_nonatomic);} -(NSString *) name {    return objc_getassociatedobject (self, &namekey);}





A practical summary of the runtime for iOS development notes

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.