object_getClass(obj)与[obj class]的区别在Object-C的类型结构中

本文深入探讨了Objective-C中的对象模型,包括实例、类、元类等核心概念,并通过代码测试详细解释了object_getClass与类方法+(Class)class的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Object-C的类型结构中,有几个比较重要的概念:Object(实例),Class(类),Metaclass(元类),Rootclass(根类),Rootclass‘s metaclass(根元类),且这些都是对象。因此标题中的“obj”这个对象可以是上面五个概念的任意一个,需要一一探讨。

1.obj为Object实例对象
在Object-C中,Object本质上是一个struct,在这个struct中会保存一个名为isa的指针,该指针会指向该Object的类。定义如下所示:

    typedef struct objc_object {  
         Class isa;  
    } *id;

下面是代码测试:

    //obj为实例变量
    id obj = [TestObject new];

    Class cls = object_getClass(obj);

    Class cls2 = [obj class];   
    
    NSLog(@"%p" , cls);    NSLog(@"%p" , cls2);

输出结果:

    2015-12-17 14:08:32.196 TestProject[658:29503] 0x100001140
    2015-12-17 14:08:32.197 TestProject[658:29503] 0x100001140

结论:当obj为实例变量时,object_getClass(obj)与[obj class]输出结果一直,均获得isa指针,即指向类对象的指针。

2.obj为Class类对象
在Objective-C中,任何类的定义都是对象。类和类的实例(对象)没有任何本质上的区别。任何对象都有isa指针。

    typedef struct objc_class *Class;    struct objc_class {
          Class isa;
          Class super_class;         
          /* followed by runtime specific details... */
   };

下面是代码测试:

    //obj为实例变量
    id obj = [TestObject new];    
    
    //classObj为类对象
    Class classObj = [obj class];

    Class cls = object_getClass(classObj);    
    Class cls2 = [classObj class];

    NSLog(@"%p" , cls);    
    NSLog(@"%p" , cls2);

输入结果:

    2015-12-17 14:25:48.785 TestProject[813:38336] 0x100001118
    2015-12-17 14:25:48.786 TestProject[813:38336] 0x100001140

结论:当obj为类对象时,object_getClass(obj)返回类对象中的isa指针,即指向元类对象的指针;[obj class]返回的则是其本身。

3.obj为Metaclass类对象
Metaclass与Class的结构是一样的,只是职能不同。Class结构中是存储Object实例的相关数据,而Metaclass则是存储Class相关的数据。

下面的测试代码:

     //obj为实例变量
    id obj = [TestObject new];    
    
    //classObj为类对象
    Class classObj = [obj class];
    
    //metaClassObj为元类对象
    Class metaClassObj = object_getClass(classObj);    
    Class cls = object_getClass(metaClassObj);    
    Class cls2 = [metaClassObj class];

    NSLog(@"%p" , cls);    
    NSLog(@"%p" , cls2);

输出结果:

    2015-12-17 14:41:23.386 TestProject[921:47694] 0x7fff78fb9118
    2015-12-17 14:41:23.387 TestProject[921:47694] 0x100001118

结论:当obj为Metaclass(元类)对象时,object_getClass(obj)返回元类对象中的isa指针,因为元类对象的isa指针指向根类,所有返回的是根类对象的地址指针;[obj class]返回的则是其本身。

4.obj为Rootclass类对象
Rootclass顾名思义就是根类,任何类的Metaclass中的isa指针都是指向根类。且结构与Class结构是一样的。

测试代码:

    //obj为实例变量
    id obj = [TestObject new];    
    
    //classObj为类对象
    Class classObj = [obj class];
    
    //metaClassObj为元类对象
    Class metaClassObj = object_getClass(classObj);    
    
    //rootClassObj为元类对象
    Class rootClassObj = object_getClass(metaClassObj);    
    Class cls = object_getClass(rootClassObj);    
    Class cls2 = [rootClassObj class];

    NSLog(@"%p" , cls);    
    NSLog(@"%p" , cls2);


输出结果:

    2015-12-17 14:52:34.633 TestProject[965:54693] 0x7fff78fb9118
    2015-12-17 14:52:34.634 TestProject[965:54693] 0x7fff78fb9118

结论:当obj为Rootclass(元类)对象时,object_getClass(obj)返回根类对象中的isa指针,因为根类对象的isa指针指向Rootclass‘s metaclass(根元类),即返回的是根元类的地址指针;[obj class]返回的则是其本身。
因为根类的isa指针其实是指向本身的,所有根元类其实就是根类,所有输出的结果是一样的。

总结:经上面初步的探索得知,object_getClass(obj)返回的是obj中的isa指针;而[obj class]则分两种情况:一是当obj为实例对象时,[obj  class]中class是实例方法:- (Class)class,返回的obj对象中的isa指针;二是当obj为类对象(包括元类和根类以及根元类)时,调用的是类方法:+ (Class)class,返回的结果为其本身。

最后,奉上一张经典的Object-C的对象模型图:

115839_HZMJ_1443665.png


转载于:https://my.oschina.net/sayonala/blog/671469

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值