Runtime official documentation

Source: Internet
Author: User
Tags encode string

OC is an object-oriented dynamic language, and as a beginner it is possible for most people to understand the concept of object-oriented, while the OC is a dynamic language with less understanding of the feature. So what is dynamic language? A dynamic language is the work of executing a compiled link to a static language at run time. This requires a runtime system in addition to the compiler to perform functions such as compiling. This system in OC is runtime.

OC Runtime is a runtime library written in C and compiled language, which makes the C language have object-oriented features.

Version

The runtime in OC is divided into two versions--modern runtime and Legacy Runtime. Now the runtime differs from the remaining runtime in the rain: The legacy runtime changes the structure of a class, you must inherit it and recompile. And now the runtime can be compiled directly.

iphone apps and 64 programs in Ox v10.5 and later use the current version of the runtime. Other projects are used by the legacy runtime.

The OC program interacts with the runtime system in three different levels: through the OC source code, by defining the method in the NSObject in the Foudation framework, and by directly invoking the run-time function.

Through the OC source code

In most cases, the runtime automatically works behind the scenes. You use it just to write and compile the OC source code.

When you compile code that contains classes and methods in OC, the compiler creates data structures and function calls to implement the dynamic nature of the language. Data structures capture the information that is declared in classes, classifications, and protocols. This includes discussing the definition of class and Protocol objects in OC, as well as extracting method selectors, instance templates, and other information from source code. The main function of the runtime is to deliver the message, as described in message passing. It is invoked through a source-code message expression.

Through the methods defined in NSObject

In cocoa, most objects are subclass objects of the NSObject class, so most objects inherit the method that he defines (except for the Nsproxy Class). So its method establishes each instance, the behavior of each class object. However, in a few cases, Nsoject only defines a template for how to do it, and it does not provide all the necessary code (abstract classes) itself. )

For example, NSObject defines an instance method that returns a string that describes the contents of a class. This is primarily used to debug GdB object print commands from a string printed in this category. The method implementation of NSObject does not know what is contained in the class, so it returns a string containing the object name and address. The subclass of NSObject can implement this method to return more details. For example, Nssarray in Foundation returns a list of descriptions that it contains objects.

The NSObject method has some simple query run-time system information. These methods allow object introspection (self-lookup). Examples of this approach are class methods, such as Iskindofclass: Ask an object to determine its class: The Ismemberofclass test object in the hierarchy of the inheritance structure, Respondstoselector, which indicates whether an object can accept a particular message, Conformstoprotocol: Determines whether an object implements a method defined in a specific protocol, Methodforselector: provides the address of a method implementation. A method like this gives the object the ability to introspect.

Functions that call the runtime directly

The runtime system is defined in the/USR/INCLUDE/OBJC directory and has a common interface that contains a series of methods and data structure dynamic shared libraries in its header file. Many of these methods allow you to use the C language to repeat how the compiler works when you write the OC code. Other forms of basic functionality are exported by means of the NSObject class. When not needed in OC, these methods make it possible to develop additional interfaces for the runtime to produce tools that enhance the development environment. However, a small run-time function can only be useful when writing an OC program. All functions are recorded in the Objective-c Runtime Reference.

Message passing mechanism

This section describes how to convert a message expression into a objc_msgsend function call, and how to find a method by name. Then explain how you can bypass dynamic binding by Objc_msgsend if you need to.

In OC, messages are not bound to the method implementation until run time. The compiler translates the message expression [receiver message] into a message-passing function, objc_msgsend. This function takes the receiver and the method name (method selector) mentioned in the message as his two main parameters: Objc_msgsend (receiver, selector). Any parameters in the message are also given to Objc_msgsend:objc_msgsend (receiver, selector, arg1, arg2, ...).

The message passing function has made all the necessary things for dynamic binding:

It first discovers the program that the method selector points to (the implementation of the method). Because the same method can be implemented separately by different classes. This exact program relies on the recipient's class.

The calling program then passes the specified arguments to the method by receiving the object (the pointer points to his data).

Finally, it passes the return value of the program when he returns the value.

Tip: The compiler generates a call to the message-passing function and is not called directly in your code.

The key to the messaging mechanism is the compiler's construction of each class and object's structure, each of which contains two basic elements: pointers to the parent class and class dispatch tables. This table lists the method selectors that define the addresses of the methods that have explicit class characteristics. For example, Setorigin:: The selector of the method is associated with the implementation of the Setorigin:: Method, shows the address of the selector Association of the method, and so on.

When a new object is created, the memory is allocated and the instance variable is initialized. First, there is a pointer variable in the object that points to its class structure. This pointer is called the ISA pointer, which enables the object to access the class, through which all of its inherited classes can be accessed by the class.

Note: Although not strictly a part of the language, the ISA pointer requires an object to run on the OC Runtime system. An object requires an equivalent objc_object struct whether it is defined in any field of this structure. However, you rarely even ever need to create your own root object, and objects that inherit from NSObject or nsproxy automatically have variable ISA pointers.

The elements and structures of these classes are as follows:


Elements and structures of a class

When a message is passed to an object, the message function follows the object's ISA pointer in the dispatch table to find it to establish the class structure of the method selector. If it cannot find the selector here, Obic_msgsend finds its parent class based on the pointer and looks for the selector in the parent class's dispatch table. Successive failures cause Objc_msgsend to inherit the structure along the class until it finds the NSObject class. Once the selector position is determined, the function calls the method in the table and passes it to the data structure of the receiving object.

This is the choice of runtime method selection implementation, in object-oriented programming terminology we can say that methods and messages are dynamically bound.

To speed up the message passing process, the runtime system caches the selector and address of the method when the method is used. Each class has a separate cache that contains the inherited methods and selectors for the methods defined in its own class. Before the dispatch table is found, the message routine is first found in the cache of the recipient object's class. (in theory, a once-in-a-time approach is likely to be used again) if the method selector is in the cache, the message delivery will be slower than the function call. If a program runs long enough to "warm up" the cache, almost all of the messages he sends can find a cached method. When the program is running, the cache grows dynamically based on the newly sent message.

Using hidden parameters

When Objc_msgsend finds a way to implement the program, it calls the program, passing all the parameters in the message. It is also passed to the program two hidden parameters: Receive object and Method selector

These parameters give explicit information about the two-part message representations that each method implements to invoke it, and they are said to be hidden because they are not declared in the source code that defines the method. They are inserted into the implementation when the code is compiled.

Although these parameters are not explicitly declared, the source code can still refer to them (just as it can receive instance variables) a method that references the receiving object as itself, referencing his own method selector as _cmd. In the following example, _cmd refers to the selector of the Strange method, which is itself the receiving object for the strange message.


Figure

Self is more useful than two parameters. In fact, this is the instance variable of the receiving object that provides a way to define the method.

Get method Address

The only way to avoid dynamic binding is to get the address of a method, which is called directly when he is a function. This can be a rare case where a specific method is executed many times in succession, and you want to save the overhead of each method call.

A method defined in NSObject, Methodforselector: You can ask a pointer to point to it, and then call him through a pointer. Methodforselector: This pointer must return the correct function type. Both the return value and the type of the parameter should also be included.

The following example shows how a program implementing the Setfilled: Method might be called:


Setfilled


The first two parameters passed to the receiving object is the Self method selector that is the _cmd program. These parameters are hidden in the syntax of the method but must be explicit when the method is called as a function.

Using Methodforselector: Avoiding dynamic binding can save most of the time of information delivery. However, the savings are noticeable only when a particular method executes many times, as shown in the For loop above.

Note: Methodforselector: is a feature provided by the runtime system rather than OC.

Dynamic Method Parsing

This chapter describes the implementation of a method that you can dynamically provide

In some cases, you may need to dynamically provide implementations for your methods. For example, when the OC declaration attribute contains the @dynamic directive:

@dynamic propertyName;

It tells the compiler that the method associated with the property will be provided dynamically.

You can implement methods Resolveinstancemethod: and Resolveclassmethod: Provide a selector for instance and class methods, respectively.

The OC method is a C function that contains at least self and _cmd two parameters. You can add a function to a class when a method uses the Class_addmethod function. Therefore, the following functions are given:

void dynamicMethodIMP(id self, SEL _cmd) {    // implementation ....}

You can also add it as a method to a class (call resolvethismethoddynamically) like this:

@implementation MyClass+ (BOOL)resolveInstanceMethod:(SEL)aSEL{    if (aSEL == @selector(resolveThisMethodDynamically)) { class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP, "[email protected]:"); return YES; } return [super resolveInstanceMethod:aSEL];}@end

The method forwarding and dynamic method parsing are largely related. A class can dynamically provide a method before the message forwarding mechanism functions. If Respondstoselector: or instancesrespondtoselector: Is invoked, the dynamic method parser first has the opportunity to provide the IMP for the selector. If you are simply implementing Resolveinstancemethod: to forward a special selector through a forwarding mechanism, you should return no for those selectors;

Dynamic loading

A OC can load links to many classes and categories when it is running. The new code is added and the classes and classifications loaded at the beginning are treated identically.

Dynamic loading can be used to do a lot of different things. For example, dynamic loading in various modules of system preferences.

In cocoa, dynamic loading is often used for program customization. Others modify the programs that you load at run time, such as when the interface builder loads custom palettes and OS X System Preferences custom modules load application preferences. Load modules to extend your application. They help you to allow but not anticipate or define. You can provide the framework for others to provide code.

Even though the runtime function provides a dynamically loaded module in the Objective-c mach-o file, the Cocoa NSBundle class provides an object-oriented dynamic loading and a more convenient interface for related service integration. You can find a detailed description of the Nsbulde in the Foudation framework reference and how it is used.

Message forwarding

If you send a message to an object that does not handle this message, the object is sent a forwardinvocation: message with the Nsinvocation object as the unique parameter before the error is realized. The nsinvocation encapsulates the original message, and the arguments pass through it.

You can do this by implementing the Forwardinvocation: method to specify a default response or by other means to avoid the error. As its name is on time, forwardinvocation: typically used to grab messages to another object.

To see the scope and intent of forwarding, you can imagine the following: First, you assume that you are designing an object that can respond to a negotiated message, and that he can respond to the response of another object. You can easily do this by sending a message to another object that contains your way of implementing the negotiation.

Further, you want your object to respond precisely to the negotiation message in another class. The way to do this is to have your class inherit the methods of other classes. However, it is impossible to arrange things this way. There's a lot of good reasons why your class and the classes that implement the negotiation are different branches of the inheritance structure.

Even if your class cannot inherit the negotiation method, you can "borrow" it by implementing a version of a method that simply passes to the instance message of another class:

- (id)negotiate{    if ( [someOtherObject respondsTo:@selector(negotiate)] )        return [someOtherObject negotiate];    return self;}

This approach can be a bit cumbersome, especially if you want your object to pass some messages to another object. You have to implement every method that you want to borrow from other classes. However, when you write code, you cannot handle a situation where you do not know all the collections of messages that you want to forward. This collection may depend on events in the runtime, and may change as new implementations of classes and new methods are implemented in the future.
Forwardinvocation: The message provides a second chance: another solution that is not so special, dynamic rather than static. It works like this: When an object responds to this message because it does not have a method selector corresponding to the message. The runtime system sends Forwardinvocation: The message notifies the object. Each object inherits a Forwardinvocation: Method from the NSObject class. However, the method version in the Nsobjcet class simply calls the Doesnotrecognizeselector:. By overriding your own version of the NSObject class implementation, Forwardinvocation: The message provides the opportunity to seize the message when another object is forwarded.
Forwardinvocation: When you forward a message, all you have to do is: 1. Determine which 2 the message is to be transmitted to. Send it past with the original parameters. The
message is sent with the Invokewithtarget: method:

- (void)forwardInvocation:(NSInvocation *)anInvocation{    if ([someOtherObject respondsToSelector:            [anInvocation selector]])        [anInvocation invokeWithTarget:someOtherObject];    else        [super forwardInvocation:anInvocation];}

The return value of the forwarded message is returned to the original sender. All types of return values can be passed to the sender, including the ID type, struct, single-precision, and double-precision floating-point numbers.
Forwardinvocation: Like a distribution center that works for unrecognized messages, pack them into different receivers. It can also be used as a transit point to send all the information to a destination. He can transfer some messages to other places, and can "swallow" some methods, so there is no response or error. Forwardinvocation: You can also merge several messages into a single response. Forwardinvocation: Doing is handing over to the realization. However, it opens the possibility of programming for the connection object on the forwarding chain.
Note: The Forwardinvocation: Method can only handle messages that do not already have a calling method in their name. For example, you want your object to forward the negotiation message to another object, and it cannot have its own negotiating method. If there is, the message will never reach nominal receiver.

Forwarding and multiple inheritance

Forward impersonation inheritance, which provides a multi-inheritance effect for OC programs, as shown in the response of an object to a message that can be implemented by borrowing or inheriting methods of other classes


In this example, an instance of the warrior class forwards the negotiation message to an instance of the diplomat class. The negotiators will appear like a diplomat. Seems to be dealing with the negotiating message, and actually it responds (though it really is a diplomat doing the job)

The object that forwards the message therefore "inherits" the method from the two inheritance hierarchies, one is its own branch and the other is the object that responds to the message. In the example above, it looks like the warrior class inherits from the diplomat as well as its own superclass.
Forwarding provides most of the features you want to inherit from multiple live. However, the biggest difference between the two is that multiple inheritance is a combination of different functions in an object. It tends to be large, multifaceted objects. On the other hand, the forwarding mechanism assigns different functions to different objects. It breaks down large problems into small objects, but associates them with the transparency of the sender of the message.

Proxy Object

Forwarding not only mimics multiple inheritance, it also enables the development of lightweight objects that represent or "overwrite" a larger number of objects. The agent represents other objects and filters the messages that are passed to him.
Such a proxy is in the remote communication in the OC programming language. The agent needs to take care of the management details of the message forwarded to the remote receiver, ensuring that the parameter values are copied and retrieved through the connection, and so on. But it does not try to do anything else; it does not copy the function of the remote object, it just gives the remote object a local but it does not try to do anything else; it does not copy the functionality of the remote object, but only gives the remote object a local address that can receive the message in another application.
Other types of proxy objects are also possible. For example, suppose you have an object that manipulates large amounts of data, perhaps it creates a complex image or reads the contents of a file on disk. Setting this object is time consuming, so you like to lazy load it when it really needs to be or when the system resources are temporarily idle. At the same time, you need at least one placeholder object, and the other objects run correctly in the application.
In this case, you can create a lightweight, incomplete object to replace him. This object can do some relative things, such as answering questions about the data, but most of the time, it only occupies a position for a large object, and when it is, forward the message to it. The proxy's forwardinvocation: The method first receives a message destined for another object, determines whether the object exists, and creates it if it does not exist. All large object messages are represented by proxies, and for other parts of the program, the proxies are the same as the large objects.

Forwarding and inheritance

While forwarding impersonation inheritance, the NSObject class never confuses both. Like Respondstoselector: And Iskindofclass: This method only looks at the structure, never on the forwarding chain. For example, if a Warrior object is asked if it will respond to the negotiating message:
if ([Awarrior respondstoselector: @selector (Negotiate)])
The answer is no, even in a sense it can be forwarded to a diplomat without mistakenly receiving a negotiated message and responding to it,
In most cases, it is not the correct answer. But it may not be. If you use forwarding to set proxy objects or extend the functionality of a class, the forwarding mechanism may be as transparent as inheritance. You need to re-implement your forwarding algorithm in Respondstoselector: and Iskindofclass: If you want your objects to behave like they actually inherit the object they are forwarding messages to.

- (BOOL)respondsToSelector:(SEL)aSelector{    if ( [super respondsToSelector:aSelector] )        return YES; else { } return NO; }

In addition to Respondstoselector: and Iskindofclass: Methods, Instancesrespondtoselector: The method should also replicate the forwarding algorithm. If the protocol is used, the Conformstoprotocol: method should also be added to the list. Similarly, if an object forwards any remote messages it receives, it should have a methodsignatureforselector that can return the final response forwarding message: The Write version. For example, if an object is able to forward a message to its proxy, you will implement Methodsignatureforselector:

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector {    NSMethodSignature* signature = [super methodSignatureForSelector:selector];    if (!signature) {       signature = [surrogate methodSignatureForSelector:selector];    }    return signature;}

You might consider encapsulating the forwarding algorithm somewhere, so that all methods include Forwardinvocation: Call him.
Note: This is an advanced technology that is only used for no other solutions. Not as a substitute for inheritance. If you have to use this technique, make sure you have a good understanding of the behavior of the class that forwards the message and the class to be forwarded.

Type encoding

To help the runtime system, the compiler encodes the return and parameter types in each method and associates the string with the method selector. In other cases, the coding system is also very useful, so the coding system is with the @encode () compiled instructions for the public to be available. When given a specified type, @encode () returns the string encoding of the specified type. This type can be any type, which can be a basic type, such as an int pointer, which can be a tag structure or union, or a class name that can be used as an argument by the sizeof () operator of the C language.
The following table lists the encoding types. Note that when you archive or distribute an object, many of them overlap the code that you use. However, the encodings in these lists cannot be used when you archive them, and you may want to archive the code that is not @encode () generated.


Encoding type


Important: OC does not support long double types. The @encode (long double) returns D as the encoded double.
The encoding of the array type is including square brackets. The number of elements in the array is specified immediately after opening the parentheses, before the array type. For example, an array that points to 12 float types will be encoded as:
[12^f]
The struct is defined within curly braces, and the Union is defined within the square brackets. The label of the struct is listed first, followed by an equal sign and the coding order of the domain. For example, the following structure:

typedef struct example {    id   anObject;     char *aString;     int anInt;} Example;

will be encoded as
{[email protected]*i}
If the definition type is (Example) or (Example) passes through @encode (), the same encoding result will be obtained. The encoding of the structure pointer carries the same number of domain information:
^{[email protected]*i}
Indirect addressing, however, removes a detailed description of the internal type
objects are treated as structs. For example, this encoding is generated by the NSObject class name @ Encode (): {nsobject=#}
A class declares only one type of ISA pointer variable
NOTE: When they declare the method in the protocol, even though the @encode () command does not return them, the runtime system uses the supplemental encoding in the following table.

declaring properties

When the compiler encounters a property declaration, it generates descriptive metadata related to the perimeter class, classification, and protocol. You can view this metadata by using a method that supports viewing the properties of classes, classifications, and protocols by name, get the @encode string type of this property, and copy it into a C-language string array property list. A list of declared properties is available for each class and protocol.

Property Types and methods

The property structure defines an opaque handle to a property descriptor.

typedef struct objc_property *Property;

You can use Class_copypropertylist and protocol_copypropertylist to retrieve the array of attributes associated with the class, loading the classification and the Protocol, respectively:

objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)objc_property_t *protocol_copyPropertyList(Protocol *proto, unsigned int *outCount)

As shown in the following example:

@interface Lender : NSObject {     float alone; } @property float alone;@end

You can get a list of his attributes:

id LenderClass = objc_getClass("Lender");unsigned int outCount;objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount);

You can use the Property_getname function to discover the name of the property

const char *property_getName(objc_property_t property)

You can specify a name in a class or protocol, and you can use Class_getproperty and protocol_getproperty to get the reference separately.

const char *name)objc_property_t protocol_getProperty(Protocol *proto, const char *name, BOOL isRequiredProperty, BOOL isInstanceProperty)

You can use the Property_getattributes function to get the name of the property and the encoded string. Learn about encoding type string details, see type coding, learn about string details, see attribute string types and examples of attribute descriptions:

const char *property_getAttributes(objc_property_t property)

Put these together, you can print a list of all the properties of a class using the following code:

id LenderClass = objc_getClass("Lender");unsigned int outCount, i;objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount);for (i = 0; i < outCount; i++) { objc_property_t property = properties[i]; fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property));}
Property type String

You can use the Property_getattributes function to get the name of the property and the encoded string, and some other properties.
The string is preceded by a t followed by the encoding type and comma, and the end is preceded by a V plus the name of the return instance variable. Between the two are separated by commas.
The following is the declaration Type property encoding


Attribute encoding

The following table shows the same property declaration and Property_getattributes: Returns the corresponding string:


Figure 1
Figure 2

Runtime official documentation

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.