iOS Runtime (2)

Source: Internet
Author: User

Forwarding: Blog Park programming Little Weng

OC is a run-time language that determines the type of an object only when the program is running, and invokes methods corresponding to the object of the class. The runtime mechanism allows us to dynamically modify all the properties and methods of a class, object, and even private methods, as well as private properties, while the program is running. The purpose of this article is to try out some of the features of the runtime sledgehammer, and a more complete approach can refer to the System API file <objc/runtime.h>,demo examples can be found in the CSDN Runtime Advanced Programming series.

Let's Go!

First look at a very common class of Father:

#import <Foundation/Foundation.h> @interface Father:nsobject@property (nonatomic, assign) int age; @end

#import "Father.h" @interface Father () {NSString *_name;} -(void) SayHello; @end @implementation father-(ID) init{    if (self = [super init]) {        _name = @ "Wengzilin";        [_name copy];        Self.age =;    }    return self;} -(void) dealloc{    [_name release];    _name = nil;    [Super Dealloc];} -(NSString *) description{    return [NSString stringwithformat:@ "name:%@, age:%d", _name, Self.age];} -(void) sayhello{    NSLog (@ "%@ says hello to you!", _name);} -(void) saygoodbay{    NSLog (@ "%@ says Goodbya to you!", _name);}

If you have not been in touch with runtime, then when I ask you: "What are the properties that the class outside of father can control?" What are the methods that can be controlled? "When you estimate that you will answer:" We can access the age property, we cannot access the _name variable, we can access the Setter/getter method for age, other methods are not. " This answer is OK, because the textbook and object-oriented thinking tells us that this is the case. However, I would say that there is one way that Apple allows and can not be limited by these rules to access what you want to access and modify what you want to modify, that is the topic of this article: runtime!

Now we are simply dividing the topic of this article into two parts: (1) Controlling private variables (2) to control private functions, because the runtime differences between them are large and the function parts are more complex

(1) Control variables

To control the private variables of a class, the first step is to know what hidden variables are in the class and what these hidden variable types are. Perhaps you would say, "Isn't that obvious?". h files are all written! ”。 If you really think so, it is very wrong, a lot of formal writing is to try to avoid a private variable in the. h file, most will choose the method. In the extension of M files, extension is the anonymous category. I guess it's also a measure to prevent hack. No matter where these variables are placed, runtime can keep them from hiding! Look at the code first, do not understand it does not matter, the following will explain:

-(void) trymember{    Father *father = [[Father alloc] init];    NSLog (@ "Before runtime:%@", [Father Description]);        unsigned int count = 0;    Ivar *members = Class_copyivarlist ([Father class], &count);    for (int i = 0; i < count; i++) {        Ivar var = members[i];        const char *membername = Ivar_getname (Var);        const char *membertype = ivar_gettypeencoding (Var);        NSLog (@ "%s----%s", membername, MemberType);}    }

Shown below:

2015-03-17 16:10:28.003 wzlcodelibrary[38574:3149577] before Runtime:name:wengzilin, AGE:272015-03-17 16:10:28.003 wzlcodelibrary[38574:3149577] [email protected] "NSString" 2015-03-17 16:10:28.003 wzlcodelibrary[38574:3149577] _ Age----I

From log we know that the Father class has two variables, one that is exposed as a property of age, the type is int, a private variable _name within a curly brace {}, and the type is nsstring. The red part of the code is the Runtime.h API,

Class_copyivarlist: Gets all the property variables of the class, the number of count record variables Ivar is a macro declared by the runtime, is the meaning of the instance variable, instance variable, defined as typedef in runtime struct Objc_ivar *ivari

Var_getname: Converting the Ivar variable to a string

Ivar_gettypeencoding: Gets the type of Ivar

If we want to _name now, do not pass father agree to secretly modify it? Let's continue: (and then the code above)

    Ivar m_name = members[0];    Object_setivar (father, M_name, @ "Zhanfen");    NSLog (@ "After runtime:%@", [Father description]);

Shown below:

2015-03-17 16:10:28.004 wzlcodelibrary[38574:3149577] after Runtime:name:zhanfen, age:27

We found that the _name attribute was forced to change, and Wengzilin changed to now Zhanfen.

(2) Controlling private functions

For a private variable, we can change the value of the variable at most, but for private functions, we can play a lot of tricks, such as: adding new functions dynamically at runtime, modifying private functions, swapping implementations of two private functions, replacing private functions ...

Similarly, the first step in control is to get all the private methods of the Father class, and we can get all the methods that are explicitly implemented in the. m file as well as the setter+getter methods of the property variables will be found:

-(void) trymemberfunc{    unsigned int count = 0;    Method *memberfuncs = Class_copymethodlist ([Father class], &count);//All methods explicitly implemented in. m files will be found for    (int i = 0; i < CO Unt i++) {        SEL name = Method_getname (Memberfuncs[i]);        NSString *methodname = [nsstring stringwithcstring:sel_getname (name) encoding:nsutf8stringencoding];        NSLog (@ "member method:%@", MethodName);}    }

Shown below:

2015-03-17 17:02:33.343 wzlcodelibrary[38748:3170794] member method:setage:2015-03-17 17:02:33.343 WZLCodeLibrary[ 38748:3170794] member METHOD:AGE2015-03-17 17:02:33.344 wzlcodelibrary[38748:3170794] member method: SAYHELLO2015-03-17 17:02:33.344 wzlcodelibrary[38748:3170794] member METHOD:SAYGOODBAY2015-03-17 17:02:33.344 WZLCODELIBRARY[38748:3170794] member METHOD:DESCRIPTION2015-03-17 17:02:33.344 wzlcodelibrary[38748:3170794] Member METHOD:DEALLOC2015-03-17 17:02:33.344 wzlcodelibrary[38748:3170794] member Method:init

Method:runtime declares a macro that represents a method that typedef struct OBJC_METHOD *method;

Class_copymethodlist: Get all methods

Method_getname: Reads a variable of type method, outputs the SEL we are familiar with in the upper layer

=========

Next we try to add new methods to try (this method is equivalent to adding a category to the Father class to extend the method):

-(void) tryaddingfunction{    class_addmethod ([Father class], @selector (method::), (IMP) myaddingfunction, "[Email Protected]:[email protected] ");    } The specific implementation, the method that imp points to is int myaddingfunction (ID self, SEL _cmd, int var1, NSString *str) {    NSLog (@ "I am added Funciton"); 
   return 10;}

-(void) trymemberfunc{    //Dynamic Add method    [self tryaddingfunction];    Count = 0;    Memberfuncs = Class_copymethodlist ([Father class], &count);//All methods explicitly implemented in. m files will be found for    (int i = 0; i < count; i++ ) {        SEL name = Method_getname (Memberfuncs[i]);        NSString *methodname = [nsstring stringwithcstring:sel_getname (name) encoding:nsutf8stringencoding];        NSLog (@ "member method:%@", methodName);    }    Try calling the new method    Father *father = [[Father alloc] init];    [Father Method:10: @ "111"];//when you typed the father instance, it was impossible to get a hint of method, only by hand knocking. And the compiler will give "-method" not found warning, you can ignore    [Father release];}

Output Result:

2015-03-17 17:02:33.345 wzlcodelibrary[38748:3170794] member method:method::2015-03-17 17:02:33.345 WZLCodeLibrary[ 38748:3170794] member METHOD:SETAGE:2015-03-17 17:02:33.345 wzlcodelibrary[38748:3170794] member method: AGE2015-03-17 17:02:33.345 wzlcodelibrary[38748:3170794] member METHOD:SAYHELLO2015-03-17 17:02:33.345 WZLCODELIBRARY[38748:3170794] member METHOD:SAYGOODBAY2015-03-17 17:02:33.345 wzlcodelibrary[38748:3170794] Member METHOD:DESCRIPTION2015-03-17 17:02:33.346 wzlcodelibrary[38748:3170794] member METHOD:DEALLOC2015-03-17 17:02:33.346 wzlcodelibrary[38748:3170794] member Method:init

As we can see, method:: The methods are indeed added to the class. Children's shoes ask, if you instantiate the Father class in other class files, can you call the-method method? The answer is yes, I've tried, and although I can't get a code hint under the MRC, just stick to the [Father Method:xx:xx] Method! (No visible @interface error will be reported under ARC)

Next, we play with the system function, the goal is to let the nsstring function of the case conversion function swap, let Apple mess:

-(void) trymethodexchange{    Method method1 = Class_getinstancemethod ([NSString class], @selector (lowercasestring) );    Method method2 = Class_getinstancemethod ([NSString class], @selector (uppercasestring));    Method_exchangeimplementations (Method1, method2);    NSLog (@ "Lowcase of WENG zilin:%@", [@ "WENG Zilin" lowercasestring]);    NSLog (@ "Uppercase of WENG zilin:%@", [@ "WENG Zilin" uppercasestring]);}

Output Result:

2015-03-17 17:20:16.073 wzlcodelibrary[38861:3180978] lowcase of WENG Zilin:weng zilin2015-03-17 17:20:16.290 WZLCODELIBRARY[38861:3180978] Uppercase of WENG Zilin:weng Zilin

iOS Runtime (2)

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.