- 1. [] means sending a message
[Receiver message] is converted by the compiler to:
Objc_msgsend (receiver, selector)
If a parameter is included
Objc_msgsend (receiver, selector, arg1, arg2, ...)
The instance object has an Isa attribute, which points to class, and the class also has an Isa attribute, pointing to Meteclass. Here's a point where any class definitions in Objective-c are objects, and their relationships are as follows:
- Get Property list: (pointer to pointer)
int // in class int// protocol
Const Char *property_getname (objc_property_t property)
Const Char *property_getattributes (objc_property_t property)
For example:
/ * ------------------------------------------------ ---------------------------------------------- * /
@interface Leader: NSObject {
float alone;
}
@property float alone;
@end
// Get the attribute columns in the class
-(void) getPropertys () {
id LenderClass = objc_getClass ("Leader");
unsigned int outCount;
objc_property_t * properties = class_copyPropertyList (LenderClass, & outCount);
for (int i = 0; i <outCount; i ++) {
objc_property_t property = properties [i];
fprintf (stdout, "% s% s \ n", property_getName (property), property_getAttributes (property));
}
}
}
When sending a message, the compiler invokes it according to the situation in the following 4 functions.
Objc_msgsend: Message return value is a simple value
Objc_msgsend_stret: Message return value is struct
Objc_msgsendsuper: Message sent to parent class
Objc_msgsendsuper_stret
1. Check whether this selector is to be ignored. For example, with garbage collection, we ignore retain, release these functions.
2. Check if the target is a nil object. The OBJC feature is that allowing any method to execute on a nil object is not Crash, because it is ignored.
3. If the above two are over, then start looking for this kind of IMP, first from the cache inside the search, and then jump to the corresponding function to execute.
4. If the cache is not found, find a way to publish.
5. If the sub-publication can not be found in the sub-category of the distribution to find, always find, until the NSObject class.
6. If you do not find it, start to enter the dynamic method resolution:
6.1 Whether the implementation of the Resolveinstancemethod, is to perform the method of positioning here
6.2 Whether the implementation of the Forwardingtargetforselector, is to perform the method of positioning here
6.3 Whether the implementation of the Forwardinvocation, is to perform the method of positioning here
6.4 is not implemented, returns a message not handle messages.
The dynamic method parsing function execution flow is as follows:
- How self takes the object that invokes the method
Self is the implicit argument in the method, and self is a dynamically passed in when the method is running.
When Objc_msgsend finds the implementation of the method, it calls the method implementation directly,
and passes all parameters in the message to the method implementation, and it also passes two hidden parameters:
1. The object that receives the message: What the self points to
2. Method selector: The content that _cmd points to
We can add instance method implementations and class method implementations separately by overloading Resolveinstancemethod: and Resolveclassmethod: Methods.
because when the runtime system cannot find the method to execute in the Cache and method sub-publication (including the superclass), runtime invokes Resolveinstancemethod:
or Resolveclassmethod: To give programmers a chance to dynamically add method implementations. We need to use the Class_addmethod function to complete the operation of adding a specific
method to a particular class:
void dynamicMethodIMP(id self, SEL _cmd) {
// implementation ....
}
@implementation myClass
+ (BOOL) resolveInstanceMethod:(SEL)aSEL {
if (aSEL == @selector(resolveThisMethodDynamically)) {
class_addMethod([self class], aSEL, (IMP)dynamicMethodIMP, "[email protected]:")
}
}
@end
Before the message forwarding mechanism executes, the Runtime system will give us another chance to rescue,
That is, by overloading-(ID) Forwardingtargetforselector: (SEL) The Aselector method replaces the recipient of the message with another object
- (
- (id)forwardingTargetForSelector:(SEL)aSelector {
if (aSelector == @selector(myMethod)) {
return alternateObject;
}
return [super forwardingTargetForSelector: aSelector];
}
The
is implemented by overriding the Forwardinvocation: method.
1. Forwardinvocation: Before the message is sent, the runtime sends an methodsignatureforselector: message to the object,
and takes the returned method signature to generate the Nsinvocation object. So we rewrite the forwardinvocation: and also rewrite the
Methodsignatureforselector: method, otherwise it throws an exception.
2. When an object cannot respond to a message because there is no corresponding method implementation, the runtime notifies the object by forwardinvocation: message.
Each object inherits the Forwardinvocation: Method from the NSObject class. However, the method implementation in NSObject simply calls the
Doesnotrecognizeselector:. By implementing our own Forwardinvocation: method, we can forward the message to other objects in the implementation of the method.
3. Forwardinvocation: The method is like a distribution center for unrecognized messages that forwards these messages to different receive objects.
or it can send all messages to the same receiving object like a transport station. It can translate a message into another message,
or simply "eat" some messages, so there is no response and no error. Forwardinvocation: Methods can also provide the same response to different messages, and
all depends on the implementation of the method. The method provides the ability to link different objects to the message chain. '
- (void)forwardInvocation:(NSInvocation *)anInvocation {
if ([someOtherObject respondsToSelector:[anInvocation selector]]) {
[anInvocation invokeWithTarget:someOtherObject];
} else {
[super forwardInvocation: anInvocation];
}
}
- The difference and connection between forwarding and inheritance
Contact:
1. OC does not have multiple inheritance, and the use of message forwarding enables multiple inheritance functions.
For example: a inherits B and C, (A:B, C) then A has both the methods in B and C.
A the same functionality can be achieved by forwarding messages to B and C.
An object forwards the message as if it had borrowed a method from another object or "inherited" it.
Difference:
1. Like respondstoselector: And Iskindofclass: This type of approach only takes into account the inheritance system and does not consider the forwarding chain.
- Objective-c Associated Objects
After OS X 10.6, the runtime system enables OBJC to dynamically add variables to objects. The following three functions are involved:
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
id objc_getAssociatedObject(id object, const void *key);
void objc_removeAssociatedObjects(id object);
The association policy is a set of enumeration constants that correspond to policies that reference associated values, that is, the reference counting mechanism of OBJC memory management.
enum {
OBJC_ASSOCIATION_ASSIGN = 0,
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
OBJC_ASSOCIATION_RETAIN = 01401,
OBJC_ASSOCIATION_COPY = 01403
};
Reference:
Http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/index.html
http://blog.csdn.net/uxyheaven/article/details/38113901
http://southpeak.github.io/blog/2014/10/25/objective-c-runtime-yun-xing-shi-zhi-lei-yu-dui-xiang/
Some understanding of Objective-c Runtime