OC类的探究分析二:类的内存结构之属性和实例方法

承接上一篇OC类的探究分析一:类与元类

🍎  直接打印LGPerson.class,发现除了isa指针,还有其他内容。


01


尝试打印地址发现,

        po 0x00000001000083a8 的打印结果是LGPerson

        po 0x0000000100357140 的打印结果是NSObject

剩余的均无法直接打印出来       



下图是定义的LGPerson类,包含一个成员变量“subject”,两个属性变量“name“和”hobby“,以及实例方法sayNB()和类方法say666(),那么这些内容是如何存储的呢?

04

打开源码查找objc_class,发现除了isa,还有superclass,cache,以及bits。cache暂时放一边(后续补充),先看一下bits。


呢么问题来了,想要查看bits里面的内容,要如何确定它的地址呢?

    点进去cache_t查看发现,cache_t是一个结构体类型,里面包含 explicit_atomic<uintptr_t> _bucketsAndMaybeMask 和 union,其他是函数和全局变量,那么cache_t的大小就是这两个成员的大小之和,为16。

03

那么,bits的地址为LGPerson的首地址(0x100008380)平移32,即 0x100008380 + 0x20 = 0x1000083a0。

 (class_data_bits_t *)0x00000001000083a0获取bits空间的指针地址,获取到指针地址,如何才能取到bits里面的数据呢?

看到这句代码注释,可以猜想到bits数据查找应当与读写相关

class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags

顺着这个想法寻找class_rw_t 相关方法

 class_rw_t *data() const {        return bits.data();  }

那么基本可以确定调用 data() 是可以得到相关数据

打印结果发现,得到的$3仍然是地址,那继续查找发现class_rw_t是结构体,那么得到的$3的地址就是指向这个结构体的。

继续阅读class_rw_t里面的内容,发现有这三个方法:

初步推断,这三个方法应该可以找到LGPerson的属性,方法,成员变量

先尝试一下properties()方法,看能不能达到想要的属性

通过打印输出结果,可以看到我们想要的内容存在以list里面,尝试打印$4.list

然而还要在进一步打印$5.ptr来拿到指针地址

先打印指针指向什么内容

打印结果显示properties()返回的是一个count=2的数组


*$6还是无法直接获取到属性,接下来再回头查看一下properties()这个方法,发现变量“v”是我们想要的东西,并且可能是通过get()方法获取。

尝试打印$7.get()



打印的内容是“name”和“hobby”这两个属性变量,由此可见成员变量”subject“和两个方法可能需要在methods()里面找。

先阅读以下methods()方法,和properties()差不多,那么可以顺这之前的思路尝试一下

method返回count=6的数组,但是打印结果为空

那么重新再分析property_array_t和method_array_t区别

进入property_array_t ——>property_t,发现property_t是一个结构体并且只有两个成员变量,如下代码

struct property_t {    const char *name;    const char *attributes;};

进入method_array_t——>method_t,method_t也是一个结构体,大致翻看一下,这里有一个 struct big{}

大致可以猜测,

    第一个成员name应该是函数名

    第二个成员type应该是函数类型

    第三个成员imp应该是当前函数的指针地址

(但是里面内容挺长的,省略号为代码余下内容,篇幅太长,截断暂时不需要的内容)

struct method_t {   

    static const uint32_t smallMethodListFlag = 0x80000000;   

    method_t(const method_t &other) = delete;   .    

    struct big {       

          SEL name;          

          const char *types;       

          MethodListIMP imp;   

    };

……

}


那么接下来尝试打印$7.get().big

打印结果显示,有sayNB(),hobby的get()、set()方法,name的get()、set()方法,以及init(),然而没有类方法say666()和成员变量subject,

那么实例方法和类方法的存储方式 不一样

(不用考虑在protocol()里寻找,因为这里面应该是与协议相关,而我们并没有去定义相关协议内容)


由此可见,只能再换个思路去寻找成员变量subject和类方法OC类的探究二:成员变量和类方法







最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容