OBJECTIVE-C Runtime Six: Supplements

Source: Internet
Author: User

super
In Objective-C, if we need to call a parent method in a class method, we usually use super as follows:

@interface MyViewController: UIViewController



@end

@implementation MyViewController



-(void) viewDidLoad {

    [super viewDidLoad];



    // do something

    ...

}



@end
We all know how to use super. The question is, how does it work?

The first thing we need to know is that super is different from self. self is a hidden parameter of the class, and the first parameter of each method implementation is self. Super is not a hidden parameter. It is actually just a "compiler identifier". It is responsible for telling the compiler to call the method of the parent class instead of the method in this class when calling the viewDidLoad method. And it actually points to the same message receiver as self. To understand this, let's first look at the definition of super:

struct objc_super {id receiver; Class superClass;};
This structure has two members:

receiver: the actual receiver of the message

superClass: pointer to the parent class of the current class

When we use super to receive messages, the compiler generates an objc_super structure. In the above example, the receiver of this structure is the MyViewController object, which is the same as self; superClass points to UIViewController, the parent class of MyViewController.

Next, when sending a message, instead of calling the objc_msgSend function, call the objc_msgSendSuper function, which is declared as follows:

id objc_msgSendSuper (struct objc_super * super, SEL op, ...);
The first parameter of the function is the objc_super structure generated earlier, and the second parameter is the selector of the method. The actual operation of this function is: from the list of methods of the superClass pointed to by the objc_super structure, search for the selector of viewDidLoad, and then call this selector with objc-> receiver.

objc_msgSend (objc_super-> receiver, @selector (viewDidLoad))
Since objc_super-> receiver is self itself, this method is actually the same as this call:

objc_msgSend (self, @selector (viewDidLoad))
To facilitate understanding, we look at the following examples:

@interface MyClass: NSObject

@end



@implementation MyClass



-(void) test {

    NSLog (@ "self class:% @", self.class);

    NSLog (@ "super class:% @", super.class);

}



@end
After calling the test method of MyClass, the output is:

2014-11-08 15: 55: 03.256 [824: 209297] self class: MyClass

2014-11-08 15: 55: 03.256 [824: 209297] super class: MyClass
As you can see from the above example, the output of both is MyClass. You can use the content introduced above to sort it out yourself.

Library-related operations
Library-related operations are mainly used to obtain library-related information provided by the system, and mainly include the following functions:

// Get the names of all loaded Objective-C frameworks and dynamic libraries

const char ** objc_copyImageNames (unsigned int * outCount);



// Get the dynamic library where the specified class is located

const char * class_getImageName (Class cls);



// Get the class names of all classes in the specified library or framework

const char ** objc_copyClassNamesForImage (const char * image, unsigned int * outCount);
Through these functions, we can understand all the libraries of a certain class, and which classes are contained in a certain library. As shown in the following code:

1
2
3
4
5
6
7
8
9
NSLog (@ "Get the dynamic library where the specified class is located");

NSLog (@ "UIView ‘s Framework:% s", class_getImageName (NSClassFromString (@ "UIView")));

NSLog (@ "Get the class name of all classes in the specified library or framework");
const char ** classes = objc_copyClassNamesForImage (class_getImageName (NSClassFromString (@ "UIView")), & outCount);
for (int i = 0; i <outCount; i ++) {
    NSLog (@ "class name:% s", classes [i]);
}
The output is as follows:

2014-11-08 12: 57: 32.689 [747: 184013] Get the dynamic library where the specified class is located

2014-11-08 12: 57: 32.690 [747: 184013] UIView ‘s Framework: /System/Library/Frameworks/UIKit.framework/UIKit

2014-11-08 12: 57: 32.690 [747: 184013] Get the class names of all classes in the specified library or framework

2014-11-08 12: 57: 32.691 [747: 184013] class name: UIKeyboardPredictiveSettings

2014-11-08 12: 57: 32.691 [747: 184013] class name: _UIPickerViewTopFrame

2014-11-08 12: 57: 32.691 [747: 184013] class name: _UIOnePartImageView

2014-11-08 12: 57: 32.692 [747: 184013] class name: _UIPickerViewSelectionBar

2014-11-08 12: 57: 32.692 [747: 184013] class name: _UIPickerWheelView

2014-11-08 12: 57: 32.692 [747: 184013] class name: _UIPickerViewTestParameters

...
Block operation
We all know that blocks bring us great convenience, and Apple continues to provide new APIs that use blocks. At the same time, Apple also provides some functions in runtime to support block-oriented operations. These functions include:

// Create a pointer to a pointer function, this function will call a specific block

IMP imp_implementationWithBlock (id block);

// return the block related to IMP (created with imp_implementationWithBlock)

id imp_getBlock (IMP anImp);



// Disassociate the block from the IMP (created using imp_implementationWithBlock) and release the copy of the block

BOOL imp_removeBlock (IMP anImp);
● imp_implementationWithBlock function: The signature of the parameter block must be of the form method_return_type ^ (id self, method_args…). This method allows us to use blocks as IMPs. As shown in the following code:

@interface MyRuntimeBlock: NSObject

@end



@implementation MyRuntimeBlock



@end

// test code
1
2
3
4
5
6
7
8
IMP imp = imp_implementationWithBlock (^ (id obj, NSString * str) {
    NSLog (@ "% @", str);
});

class_addMethod (MyRuntimeBlock.class, @selector (testBlock :), imp, "[email protected]: @");

MyRuntimeBlock * runtime = [[MyRuntimeBlock alloc] init];
[runtime performSelector: @selector (testBlock :) withObject: @ "hello world!"];
The output is

2014-11-09 14: 03: 19.779 [1172: 395446] hello world!
Weak reference operation
// Load the object referenced by the weak reference pointer and return

id objc_loadWeak (id * location);



// Store the new value of the __weak variable

id objc_storeWeak (id * location, id obj);
● objc_loadWeak function: This function loads an object referenced by a weak pointer and returns it after performing retain and autoreleasing operations on it. This way, the object can maintain a long enough life cycle when the caller uses it. This function is typically used in any expression that uses the __weak variable.

● objc_storeWeak function: This function is typically used when the __weak variable is used as an assignment object.

The specific implementation of these two functions is not an example here. Interested partners can refer to the introduction of __weak implementation in Objective-C Advanced Programming: iOS and OS X Multithreading and Memory Management.

Macro definition
In runtime, we also define some macro definitions for our use. Some values we will often use, such as YES / NO for BOOL values, and some values are not commonly used, such as OBJC_ROOT_CLASS. Here we make a brief introduction.

Boolean value
#define YES (BOOL) 1

#define NO (BOOL) 0
These two macro definitions define constants representing Boolean values. It should be noted that the value of YES is 1, not the value of non-0.

Null value
#define nil __DARWIN_NULL

#define Nil __DARWIN_NULL
Where nil is used for empty instance objects and Nil is used for empty class objects.

Distribution function prototype
#define OBJC_OLD_DISPATCH_PROTOTYPES 1
This macro indicates whether the dispatch function must be converted to the appropriate function pointer type. When the value is 0, conversion must be performed

Objective-C root class
#define OBJC_ROOT_CLASS
If we define an Objective-C root class, the compiler will report an error indicating that the class we defined does not specify a base class. In this case, we can use this macro definition to avoid this compilation error. This macro is available after iOS 7.0.

In fact, in the declaration of NSObject, we can see the figure of this macro as follows:

__OSX_AVAILABLE_STARTING (__ MAC_10_0, __IPHONE_2_0)

OBJC_ROOT_CLASS

OBJC_EXPORT

@interface NSObject <NSObject> {

    Class isa OBJC_ISA_AVAILABILITY;

}
We can refer to this way to define our own root class.

Local variable storage duration
#define NS_VALID_UNTIL_END_OF_SCOPE
This macro indicates that the values stored in some local variables should not be freed by the compiler during optimization.

We mark local variables as type ids or pointers to ObjC object types, so that the values stored in these local variables are not forced to be released by the compiler during optimization. Instead, these values are stored until the variable is assigned again or until the scope of the local variable ends.

Associated Object Behavior
enum {

    OBJC_ASSOCIATION_ASSIGN = 0,

    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,

    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,

    OBJC_ASSOCIATION_RETAIN = 01401,

    OBJC_ASSOCIATION_COPY = 01403

};
These values have been introduced previously and will not be repeated here.

to sum up
At this point, the finishing of the runtime in this series is over. Of course, this is just an induction of some basic knowledge of runtime, trying to play a role in attracting a lot of attention. There are many interesting things about runtime that the reader needs to explore by himself.

Objective-C Runtime Runtime 6: Findings

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.