iOS原理篇(一) OC对象的本质

一、OC对象

OC对象有instance对象(实例对象)、class对象(类对象)、meta-class对象(元类对象)

1.instance对象的结构是struct objc_object

instance对象在内存中存储的信息包括:
(1)isa指针
(2)其他成员变量

typedef struct objc_object *id;
struct objc_object {
    Class isa;
};

2.class对象、meta-class对象的结构是struct objc_class

类对象在内存中存储的信息主要包括:
(1)isa指针
(2)superclass指针
(3)类的属性信息(@property)、类的对象方法信息(instance method)
(4)类的协议信息(protocol)、类的成员变量信息(ivar)

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

3.objc_class继承objc_object。

objc_object是所有对象的根对象。


struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
}

4.获取实例对象、类对象、元类对象

//instance对象(实例对象)
NSObject *object1 = [[NSObject alloc] init];
//class对象(类对象)
//class方法返回的一直是class对象(类对象)
Class objectClass1 = [object1 class];
Class objectClass2 = object_getClass(object1);
Class objectClass3 = [NSObject class];
//meta-class对象(元类对象)
//将类对象当做参数传入,获得元类对象
Class metaClass = object_getClass(objectClass3);
NSLog(@"metaClass - %p", metaClass);

快捷记忆图片

 二、对象的isa指针和superclass指针
 

以UIView为例,UIView---继承--->UIResponder---继承--->NSObject

1、isa指针
instance对象的isa指针指向class对象(view的isa是UIView)
class对象的isa指针指向meta-class对象(UIView的isa是UIView(meta-class))
meta-class对象的isa指针指向基类的meta-class对象
2、superclass指针
class对象的superclass指针指向父类的class对象
如果没有父类,superclass指针为nil
meta-class对象的superclass指针指向父类的meta-class对象
基类的meta-class的superclass指针指向基类的class对象

3、instance调用对象方法的轨迹,isa找到class,方法不存在,就通过superclass找父类
class调用类方法的轨迹,isa找meta-class,方法不存在,就通过superclass找父类

苹果源码:opensource.apple.com/tarballs
objc4源码下载:https://opensource.apple.com/tarballs/objc4/

三、补充

1.NSObject对象占用多少内存? 

系统分配了16个字节给NSObject对象,16字节对齐。object中isa指针占用8字节。

类的数据在内存中只存在一份。NSObject UIView 内存只有一份。

2.meta-class存储着一个类的所有类方法和类属性。每个类都会有一个单独的meta-class,因为每个类的类方法基本不可能完全相同。

获取元类
Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}
/判断currentClass是否为元类
BOOL isMetaClass = class_isMetaClass([obj class]);

3.isMemberOfClass,isKindOfClass 内部实现

// 这个是对象方法,传入的实例对象->所指向的类对象 和 传入的类对象 对比
- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
//self是实例对象
//[self class];self的类
}
// 这个是对象方法,传入的实例对象->ISA(类或类的父类) 和 传入的类对象 对比
- (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = [self class]; tcls; tcls = tcls->getSuperclass()) {
        if (tcls == cls) return YES;
    }
    return NO;
//self是实例对象
//Class tcls = [self class];self的类
//tcls = tcls->getSuperclass();self的父类
}

// 这个是类方法,传入的类对象->ISA(元类) 和 传入的类对象 对比
+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
//self是类对象
//self->ISA()是元类 
}
// 这个是类方法,传入的类对象->ISA(元类或元类的父类) 和 传入的类对象 对比
+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = self->ISA(); tcls; tcls = tcls->getSuperclass()) {
        if (tcls == cls) return YES;
    }
    return NO;
//self是类对象
//Class tcls = self->ISA();tcls是self类的元类 (tcls为元类)
//tcls = tcls->getSuperclass();tcls是tcls元类的父类  (tcls为元类)
}

//NSObject 的元 类对象 的 superClass 指向 的是 NSObject 的类对象
NSLog(@"%d", [[NSObject class] isKindOfClass:[NSObject class]]); // 结果为:  1
NSLog(@"%d", [[NSObject class] isMemberOfClass:[NSObject class]]);// 结果为: 0
NSLog(@"%d", [[UIView class] isKindOfClass:[UIView class]]);// 结果为:  0
NSLog(@"%d", [[UIView class] isMemberOfClass:[UIView class]]);// 结果为:  0

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iOS KunPeng

一天写不出一片好文章,感谢!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值