前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Conclusion of objective-C structure

Conclusion of objective-C structure

作者头像
Mitchell
发布2018-09-30 09:39:27
8460
发布2018-09-30 09:39:27
举报
文章被收录于专栏:西二旗一哥

The isa pointer of Instance and Class

  • Firstly, let's have a look at the struct objc_class * of Class, objc_class inherits from objc_object which only have a isa.
代码语言:javascript
复制
//Class is in effect a struct pointer of (objc_class *)
typedef struct objc_class *Class;  
//The struct objc_class
struct objc_class : objc_object {  
    Class superclass;
    cache_t cache;
    class_data_bits_t bits;
    class_rw_t *data() { 
        return bits.data();
    }
    void setData(class_rw_t *newData) {
        bits.setData(newData);
    }
    //many set/get methods...
}
struct objc_object {  
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};
struct class_rw_t {  
    // Be warned that Symbolication knows the layout of this structure.
    uint32_t flags;
    uint32_t version;
    const class_ro_t *ro;
    method_array_t methods;
    property_array_t properties;
    protocol_array_t protocols;
    Class firstSubclass;
    Class nextSiblingClass;
    char *demangledName;
#if SUPPORT_INDEXED_ISA
    uint32_t index;
#endif
//some other methods ...
}
  • In the struct code above, we can see that methods, propertys, protocols and some other values are stored in the class's struct.
  • Here is a picture how a class's superclass pointer point to its superclass.
Class Structure
Class Structure
  • Take a look at initialization process of NSObject:
代码语言:javascript
复制
+ (id)alloc {
    return _objc_rootAlloc(self);
}
id _objc_rootAlloc(Class cls)  
{
    return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}
static ALWAYS_INLINE id  
callAlloc(Class cls, bool checkNil, bool allocWithZone=false)  
{
//This command is to check (checkNil && !cls)'s result which tell complier the result is more possible to be false;
    if (slowpath(checkNil && !cls)) return nil;
#if __OBJC2__
// hasCustomAWZ() method means class or superclass has default alloc/allocWithZone: implementation, note this is is stored in the metaclass
    if (fastpath(!cls->ISA()->hasCustomAWZ())) {
// FAST_ALLOC means
//   FAST_HAS_CXX_CTOR is set
//   FAST_REQUIRES_RAW_ISA is not set
//   FAST_SHIFTED_SIZE is not zero
// FAST_ALLOC does NOT check FAST_HAS_DEFAULT_AWZ because that bit is stored on the metaclass.
        if (fastpath(cls->canAllocFast())) {
            bool dtor = cls->hasCxxDtor();
            id obj = (id)calloc(1, cls->bits.fastInstanceSize());
            if (slowpath(!obj)) return callBadAllocHandler(cls);
            obj->initInstanceIsa(cls, dtor);
            return obj;
        }
        else {
            // Has ctor or raw isa or something. Use the slower path.
            id obj = class_createInstance(cls, 0);
            if (slowpath(!obj)) return callBadAllocHandler(cls);
            return obj;
        }
    }
#endif
    if (allocWithZone) return [cls allocWithZone:nil];
    return [cls alloc];
}
//The slow Path: class_createInstance
//The fast path: initInstanceIsa, return value type is objc_object;
inline void  
objc_object::initInstanceIsa(Class cls, bool hasCxxDtor)  
{
    assert(!cls->instancesRequireRawIsa());
    assert(hasCxxDtor == cls->hasCxxDtor());
    initIsa(cls, true, hasCxxDtor);
}
//Here is the struct of objc_object
struct objc_object {  
private:  
    isa_t isa;
//other methods
}
  • Here is a image!

Instance' and class' method calling trace

  • There is a classical image:
conclusion of instance and class isa trace
conclusion of instance and class isa trace
  • All in all:
    • Instance's isa point to its Class
    • Class' isa point to its meta-class
    • Meta-class' isa point to its root class' meta-class.
    • Class' superclass pointer point to its superclass' Class. If Class have no superclass, it's superclass point to nil.
    • Meta-class superclass point to its superclass' meta-class.
    • The superclass of root class' meta-class point to root class' Class.
  • Instance call trace
    • Instance can use its isa to find its' Class ßand check if the method is exist int its Class's methodList, and then check the superclass if the method not exist.
  • Class call trace
    • Class can use its isa find meta-class, it will contine find its superclass via superclass pointer if the method doesn't exist.
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • The isa pointer of Instance and Class
  • Instance' and class' method calling trace
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档