Runtime in iOS development

Source: Internet
Author: User

Runtime in iOS development
1. Introduction to runtime

  • RunTime is short for RunTime. OC isRuntime MechanismThat is, some mechanisms at runtime, the most important of which is the message mechanism.
  • For C language,Function calling determines which function to call during compilation..
  • For OC functionsDynamic call ProcessDuring compilation, you cannot decide which function to call. You can only find the corresponding function to call based on the function name during actual running.
  • Facts have proved that:
    • In the compilation phase, OC canCall any functionEven if this function is not implemented, no error will be reported if it is declared.
    • In the compilation phase, C language callsUnimplemented FunctionsAn error is reported.
  • Before using runtime, configure the environment as follows: Enable Strict: Select No.

Ii. Functions of runtime

1. Send messages
• The essence of method calling is to let an object send messages.
• Objc_msgSend: only objects can send messages. Therefore, it starts with objc.
• Before using the message mechanism, you must import # import <objc/message. h>
• Enter the file path and run the clang-rewrite-objc main. m command on the terminal to view the final generated code.

1     // NSObject *objc = [NSObject alloc];2     NSObject *objc = objc_msgSend([NSObject class], @selector(alloc));3 4     // objc = [objc init];5     objc = objc_msgSend(objc, @selector(init));6     7     NSLog(@"%@",objc);

Message mechanism function: [call known private methods]

For example, the Person class has two private methods.

1 # import <Foundation/Foundation. h> 2 3 @ interface Person: NSObject 4 5 @ end 6 7 @ implementation Person 8 9-(void) run :( NSInteger) meter10 {11 NSLog (@ "% ld Meters Running", meter); 12} 13 14-(void) eat15 {16 NSLog (@ "eat "); 17} 18 19 @ end
1 # import <objc/message. h> 2 # import "Person. h "3 4 @ interface ViewController () 5 6 @ end 7 8 @ implementation ViewController 9 10-(void) viewDidLoad {11 [super viewDidLoad]; 12 13 // Person * p = [Person alloc]; 14 Person * p = objc_msgSend ([Person class], @ selector (alloc )); 15 16 // p = [p init]; 17 p = objc_msgSend (p, @ selector (init); 18 19 // call eat20 // [p eat]; 21 objc_msgSend (p, @ selector (eat); 22 23 // runtime24 // start after the method number, which is sorted by the method parameters in Order 25 // objc_msgSend (id self, SEL op ,...) 26 objc_msgSend (p, @ selector (run :), 20); 27}

// You can call the class method in either of the following ways:
// The first method is called by class name.
[Person eat];
// The second method is called through a class object.
[[Person class] eat];

// Call the class method with the class name. The underlying layer will automatically convert the class name into a class object call]
// Essence: Let the Class Object send messages]
Objc_msgSend ([Person class], @ selector (eat ));

Speaking of this, I have to ask: how do I find the corresponding method of the object to call?

To answer this question, you must first know where the method is saved? ---> The object method is saved to the class, and the class method is saved to the meta class. Each class has a method list methodList.
1. Search for methods in the corresponding class based on the isa pointer of the object. Isa: identifies the class to which the corresponding method points to the class called by the method.
2. The corresponding Method (Method name) can be found in the Method list based on the input Method number (SEL ).
3. Find the function implementation based on the method name (function entry.

Message Mechanism principle: the object maps the table to find the corresponding method implementation based on [method id sel.

 

2. Exchange Methods

• Development and application scenarios: The methods and functions provided by the system cannot meet the requirements. Some functions are extended for the methods provided by the system and the original functions are maintained.
• Method 1: Inherit the system class and override the method.
• Method 2: Use runtime and exchange methods.

Requirement: provides the imageNamed method with the function to determine whether the image is successfully loaded every time it is loaded.

// Step 1: first create a classification and define a method that can load and print images + (UIImage *) wm_imageNamed :( NSString *) name;
// Step 2: Exchange imageNamed and wm_imageNamed to call imageNamed and indirectly call wm_imageNamed.

Write a classification of UIImage + Image. h:

1 # import <UIKit/UIKit. h> 2 3 @ interface UIImage (Image) 4 5 // Add a prefix to the method and distinguish it from the System Method 6 // load the Image 7 + (UIImage *) wm_imageNamed :( NSString *) name; 8 9 @ end
1 # import "UIImage + Image. h "2 # import <objc/message. h> 3 4 @ implementation UIImage (Image) 5 6 // call when loading the class, only 7 + (void) will be called once) load 8 {9 // implement wm_imageNamed and imageNamed10 11 // obtain Method: Method Name 12 // obtain class Method 13 // class: method 14 // SEL: Method number 15 Method imageNameMethod = class_getClassMethod (self, @ selector (imageNamed :)); 16 17 Method wm_imageNameMethod = class_getClassMethod (self, @ selector (wm_imageNamed :)); 18 19 method_exchangeImplementations (imageNameMethod, steps); 20 21} 22 23 // load image 24 // judge 25 + (UIImage *) wm_imageNamed :( NSString *) name26 {27 // here wm_imageNamed is called: Actually imageNamed :. 28 UIImage * image = [UIImage wm_imageNamed: name]; 29 30 if (image = nil) {31 NSLog (@ "loading failed"); 32} 33 34 return image; 35} 36 @ end

External Use: You can use the imageNamed method to determine whether the image is successfully loaded without importing the category header file.

 1 #import "ViewController.h" 2  3 @interface ViewController () 4  5 @end 6  7 @implementation ViewController 8  9 - (void)viewDidLoad {10     [super viewDidLoad];11 12     [UIImage imageNamed:@"123"];13 }

3. Dynamic Addition Method

Development and application scenarios: if there are many methods in a class, loading the class to the memory is more resource-consuming, You need to generate a ing table for each method. You can dynamically add methods to a class.

So why dynamic addition method?

OC is mostly loaded lazily, and some methods may not be called for a long time, saving memory. For example, e-commerce, video, social networking, paid items: membership mechanism, which is available only to members.

Import the header file of the Person class in ViewController and call run: method. The Person class does not have the run: method declaration and implementation.

1 @ implementation ViewController 2 3-(void) viewDidLoad {4 [super viewDidLoad]; 5 6 // _ cmd: Method number 7 NSLog (@ "% @", self, NSStringFromSelector (_ cmd); 8 9 Person * p = [[Person alloc] init]; 10 // default person. The run method is not implemented. It can be called by using javasmselector, however, an error is reported. 11 // The dynamic addition method will not report the error 12 [p performSelector: @ selector (run :) withObject: @ 20]; 13 14} 15 @ end
1 # import <Foundation/Foundation. h> 2 3 @ interface Person: NSObject 4 5 @ end 6 7 8 # import <objc/message. h> 9 10 @ implementation Person11 12 // define the function 13 // No return value, there are 14 parameters // The default OC method has two implicit parameters, self, _ 000015 void run (id self, SEL _ cmd, NSNumber * meter) {16 NSLog (@ "% @ meter running", meter ); 17} 18 19 // when to call: when an object calls an unimplemented method, this method will be called for processing and the corresponding method list will be passed over. 20 // function: There is no implementation method to solve the problem. The dynamic adding method 21 + (BOOL) resolveInstanceMethod :( SEL) sel {22 23 // can be used to judge, the unimplemented method is not the method we want to dynamically add 24 if (sel = @ selector (run :)) {25 // Add run dynamically: method 26 27 // first parameter class: Add Method 28 // second parameter SEL: add method 29 // third parameter IMP: function implementation (function address) 30 // The fourth parameter type: function type. (Return Value + parameter type) v indicates void; @ indicates object-> self ;: indicates that SEL-> _ cmd can pass nil31 class_addMethod (self, sel, (IMP) run, "v @:"); 32 33 return YES; 34} 35 return [super resolveInstanceMethod: sel]; 36} 37 @ end

Class_addMethod description, which is provided in the official documentation:

1. The function must have at least two parameters: self and _ cmd.

2. For details about the fourth parameter type, refer to the Type encoding type Encodings.

3. The second and third characters of Type must be @ And:. The first character is the Type of the function return value. (Nil can also be used to test the Type)

Console print information:

09:52:53. 634 Runtime (Dynamic addition method) [38020: 1362250] <ViewController: 0x7f9f69d21460> viewDidLoad
09:52:53. 634 Runtime (Dynamic addition method) [38020: 1362250] ran 20 meters

4. Add attributes to a category

Principle: To declare attributes for a class, the essence is to add associations for this class.
 
Attribute nature: Associate attributes with an object
 
Scenario: [add attributes to the system class]

For example, requirement: Add a name attribute to NSObject and dynamically Add the attribute-> runtime

New category NSObject + Property

1 # import <Foundation/Foundation. h> 2 3 @ interface NSObject (Property) 4 5 // @ property is used in classification: only get is generated and set method declaration is not generated, set Method implementation and underline member attributes 6 @ property NSString * name; 7 8 @ end 9 10 11 # import <objc/message. h> 12 13 @ implementation NSObject (Property) 14 15-(void) setName :( NSString *) name16 {17 18 // save name19 // Add attributes dynamically = nature: associate a property and value of an object 20/* 21 object: The object to which the object is saved. 22 key: the attribute used to save the property name 23 value: Save the value 24 policy: policy, strong, weak25 */26 objc_setAssociatedObject (self, "name", name, tags); 27 28} 29 30-(NSString *) name31 {32 return objc_getAssociatedObject (self, "name"); 33} 34 @ endCATEGORY NSObject + Property 1 # import "ViewController. h "2 # import" Person. h "3 # import" NSObject + Property. h "4 5 @ interface ViewController () 6 7 @ end 8 9 @ implementation ViewController10 11-(void) viewDidLoad {12 [super viewDidLoad]; 13 14 NSObject * objc = [[NSObject alloc] init]; 15 16 objc. name = @ "123"; 17 18 NSLog (@ "% @", objc. name); 19} 20 @ endController ViewController

Console print information:

10:19:19. 100 Runtime (add attributes to a category) [38433: 1382316] 123

5. dictionary-to-model conversion

Because the dictionary to model more content, open a new blog details please CLICK: http://www.cnblogs.com/wm-0818/p/5394567.html

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.