Inquisitive objective-c Runtime (2)-Object & class & Meta class

Source: Internet
Author: User

Chun tips focus on iOS development inquisitive objective-c Runtime (2)-Object & class & Meta class

The last note tells the details of self and super in OBJC runtime, this note is mainly about the details of Object & Class & Meta class in the OBJC runtime.

Exercise content

What is the result of the following code?

@interface Sark : NSObject@end@implementation Sark@endint main(int argc, const char * argv[]) {    @autoreleasepool {        BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];        BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];        BOOL res3 = [(id)[Sark class] isKindOfClass:[Sark class]];        BOOL res4 = [(id)[Sark class] isMemberOfClass:[Sark class]];        NSLog(@"%d %d %d %d", res1, res2, res3, res4);    }    return 0;}

The result of the operation is:

2014-11-05 14:45:08.474 Test[9412:721945] 1 0 0 0
Here's a couple of concepts first. What is ID

The ID is defined in objc.h as follows:

/// A pointer to an instance of a class.typedef struct objc_object *id;

As the note says, the ID is a pointer to a objc_object struct.

id 这个struct的定义本身就带了一个 *, 所以我们在使用其他NSObject类型的实例时需要在前面加上 *, 而使用 id 时却不用。

So what's objc_object?

objc_object is defined in objc.h as follows:

/// Represents an instance of a class.struct objc_object {    Class isa;};

At this point we know that the object in Objective-c will be converted to the struct of C at the end, and there is an ISA pointer in the struct that points to its class class.

So what is class?

The following are defined in Objc.h:

/// An opaque type that represents an Objective-C class.typedef struct objc_class *Class;

We can see that the class itself points to a struct of C objc_class .

Continue to look in the runtime.h objc_class as defined below:

struct objc_class {    Class isa  OBJC_ISA_AVAILABILITY;    #if !__OBJC2__    Class super_class                                        OBJC2_UNAVAILABLE;    const char *name                                         OBJC2_UNAVAILABLE;    long version                                             OBJC2_UNAVAILABLE;    long info                                                OBJC2_UNAVAILABLE;    long instance_size                                       OBJC2_UNAVAILABLE;    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;    #endif} OBJC2_UNAVAILABLE;

In the struct,Isa points to the owning class, and Super_class points to the parent category.

Keep looking.

Download OBJC source code, in objc-runtime-new.h , we found the objc_class following definition:

struct objc_class : objc_object {    // Class ISA;    Class superclass;       ...    ...}

Enlightened, we see that in Objective-c's philosophy of design, everything is an object. Class is also an object in the design itself. and the corresponding class of this class object, we call it Meta Class . That is, the Isa in the class struct is pointing to it Meta Class .

Meta Class

According to the above description, we can Meta Class interpret it as 一个Class对象的Class . To put it simply:

    • When we send a message to a NSObject object, this message is found in the method list of the object's class
    • When we send a message to a class, this message is found in the method list of the class's meta class

The Meta class itself is also a class, and it has its own Isa and super_class pointers, just like any other class. See:

    • Each Class has an Isa pointer pointing to a unique meta Class
    • Each meta-class ISA pointer points to the topmost meta class (NSObject's meta class in the figure)
    • 最上层的Meta Class的isa指针指向自己,形成一个回路
    • Each meta class's super class pointer points to the Meta class of its original class super class.但是最上层的Meta Class的 Super Class指向NSObject Class本身
    • The top NSObject class super class points to nil
Doubts

To get a clearer idea of the entire function call process, we use clang -rewrite-objc main.m overrides to obtain the following code:

 BOOL Res1 = ((bool (*) (ID, SEL, Class)) (void *) objc_msgsend) ((ID) ((Class (*) (ID, SEL) (void *) objc_msgsend) ((ID) objc_get Class ("NSObject"), Sel_registername ("class"), Sel_registername ("Iskindofclass:"), ((Class (*) (ID, sel)) (void *) OBJC _msgsend) ((ID) objc_getclass ("NSObject"), Sel_registername ("Class"))); BOOL Res2 = ((bool (*) (ID, SEL, Class)) (void *) objc_msgsend) ((ID) ((Class (*) (ID, SEL) (void *) objc_msgsend) ((ID) objc_ GetClass ("NSObject"), Sel_registername ("class"), Sel_registername ("Ismemberofclass:"), ((Class (*) (ID, sel)) (void * ) (Objc_msgsend) ((ID) objc_getclass ("NSObject"), Sel_registername ("Class"))); BOOL Res3 = ((bool (*) (ID, SEL, Class)) (void *) objc_msgsend) ((ID) ((Class (*) (ID, SEL) (void *) objc_msgsend) ((ID) objc_ GetClass ("Sark"), Sel_registername ("class"), Sel_registername ("Ismemberofclass:"), ((Class (*) (ID, sel)) (void *) Objc_msgsend) ((ID) objc_getclass ("NSObject"), Sel_registername ("Class"))); BOOL Res4 = ((bool (*) (ID, SEL, Class)) (void *) objc_msgsend) ((ID) ((Class (*) (ID,SEL) (void *) objc_msgsend) ((ID) objc_getclass ("Sark"), Sel_registername ("class")), Sel_registername (" Ismemberofclass: "), ((Class (*) (ID, SEL)) (void *) objc_msgsend) ((ID) objc_getclass (" NSObject "), Sel_registername (" Class "));
Look at the first two calls:
    • The outermost layer is the objc_msgSend function that forwards the message.
    • The first parameter of a function is(id)((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("class"))
    • The second parameter of the function is the forwarded selector
    • The third parameter of the function is((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("class"))

We notice that the first parameter and the third parameter correspond to the rewrite [NSObject class] , which is to use objc_msgSend the message to send the @selector (class) to the NSObject class.

Open the OBJC source code and find the implementation in object.mm + (Class)class as follows:

+ (Class)class {    return self;}

So the object itself is returned to the class. Look at the following output:

NSLog(@"%p", [NSObject class]);NSLog(@"%p", [NSObject class]);2014-11-05 18:48:30.939 Test[11682:865988] 0x7fff768d40f02014-11-05 18:48:30.940 Test[11682:865988] 0x7fff768d40f0

Continuing to open the OBJC source code, in object.mm , we found isKindOfClass the following implementation:

- (BOOL)isKindOf:aClass{    Class cls;    for (cls = isa; cls; cls = cls->superclass)         if (cls == (Class)aClass)            return YES;    return NO;}

On the above Meta class diagram and implementation, we can see

    • When the NSObject class object is compared for the first time, it gets its Isa NSObject Meta class, which NSObject Meta class and NSObject class are not equal.

(This should be called for a class function, so Isa is a meta-class, and if it is an instance object, ISA is not a meta-class but a class object)

    • Then take the super class of NSObject's meta class, and this time it becomes the NSObject class, so return equal

So the first output of the above is Yes .

We are looking at the realization of ' ismemberofclass ':

- (BOOL)isMemberOf:aClass{    return isa == (Class)aClass;}

In summary, the current Isa points to NSObject's Meta class, so it is not equal to the NSObject class.

So the second output above is NO .

Keep looking at the back two calls:
    • Sark class Isa points to Sark's meta class, which is not equal to Sark class.
    • Sark Meta class's super class points to NSObject Meta class, which is not equal to Sark class
    • NSObject Meta class Super class points to NSObject class, and Sark class is not equal
    • NSObject class's super class points to nil, and Sark class is not equal

So the result of the last two calls is output to NO .

下一篇博客的主要分享的内容是关于 Objective C Runtime中 消息和Category 的学习笔记。

    • This article is about objective C Runtime's learning notes. If there are any wrong places, please correct me.
    • Thanks @ Tang Qi _boy and @sunnyxx share the topic.
    • This article was published by @chun in Chun Tips.
    • Copyright Disclaimer: Free Reprint-Non-commercial-non-derivative-retain attribution | Creative Commons by-nc-nd 3.0

Chun tips is being used much more.

Copyright©2015-chun Ye- Powered by Octopress

Inquisitive objective-c Runtime (2)-Object & class & Meta class

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.