美文网首页Objective - C 底层
Objective - C 对象的本质(三)对象的分类

Objective - C 对象的本质(三)对象的分类

作者: 爱玩游戏的iOS菜鸟 | 来源:发表于2020-04-26 12:47 被阅读0次

(一)对象的分类

OC中的对象,主要有3种:instance对象(实例对象)class对象(类对象)meta-class对象(元类对象),我们在前两章讲的是instance对象

(1)instance对象
  1. instance对象就是通过类alloc出来的对象,同一个类多次alloc生成不同的实例对象,分别处在不同的内存地址
  2. instance对象中包含信息:isa指针、其他成员变量
(2)class对象
  1. class对象是唯一的,一个类只有一个class对象
  2. class对象在内存中存储的信息主要包括:
  • isa指针
  • superclass指针
  • 类的属性信息(@property)、类的对象方法信息(instance method)
  • 类的协议信息(protocol)、类的成员变量信息(ivar)
  • ......等等

如何得到一个类的类对象呢?

  ZQPerson *personInstance = [[ZQPerson alloc]init];//ZQPerson实例对象
  personInstance.no = 432423;

  //下面的三个都是ZQPerson的class对象(类对象)
  Class personClass1 = [personInstance class];
  Class personClass2 = [ZQPerson class];//不管调用多少次class方法都只能获取类对象
  Class personClass3 = object_getClass(personInstance);//Runtime API

NSLog(@"\nclass对象:\n %p \n %p \n %p",personClass1,personClass2,personClass3);//
  /*
    instance对象:
      0x10060ffb0
    class对象:地址都相同
      0x1000024c0
      0x1000024c0
      0x1000024c0
  */
(3)meta-class对象
  1. 每个类在内存中有且只有一个meta-class对象
  2. meta-class对象和class对象的内存结构是一样的,但是用途不一样,在内存中存储的信息主要包括:
  • isa指针
  • superclass指针
  • 类的类方法信息(class method)
  Class personMetaClass = object_getClass(personClass1);
  NSLog(@"\nmeta-class对象:\n %p",personMetaClass);
  /*
    meta-class对象:
      0x1000024b8
  */

内存结构一样,是指class对象和meta-class对象结构一样,只不过存储的信息不同,用途不同,如:class对象也有类方法信息,只是里面为空,meta-class也是对应的;

//判断某个对象是否是元类对象
NSLog(@"%d",class_isMetaClass(personMetaClass));//1
(4) object_getClass方法

在上面我们发现多次调用了object_getClass方法,传入的对象也不同,得到不同的结果,是为什么呢?

我们在runtime源码objc-class.mm中可以找到:

Class object_getClass(id obj)
{
    //1.如果传入的是istance对象,返回class对象
    //2.如果传入的是class对象,返回的是meta-class对象
    //3.如果传入的是meta-class,返回NSObject(基类)的meta-class对象
    if (obj) return obj->getIsa();
    else return Nil;
}
(5) objc_getClass方法

我们再查看一下objc_getClass方法:

Class objc_getClass(const char *aClassName)
{
    if (!aClassName) return Nil;

    // NO unconnected, YES class handler
    return look_up_class(aClassName, NO, YES);
}


Class 
look_up_class(const char *name, 
              bool includeUnconnected __attribute__((unused)), 
              bool includeClassHandler __attribute__((unused)))
{
    if (!name) return nil;

    Class result;
    bool unrealized;
    {
        runtimeLock.lock();
        result = getClassExceptSomeSwift(name);//调用这个方法,继续跟进
        unrealized = result  &&  !result->isRealized();
        if (unrealized) {
            result = realizeClassMaybeSwiftAndUnlock(result, runtimeLock);
            // runtimeLock is now unlocked
        } else {
            runtimeLock.unlock();
        }
    }

    ...//省略代码
    return result;
}


static Class getClassExceptSomeSwift(const char *name)
{
    runtimeLock.assertLocked();

    // Try name as-is
    Class result = getClass_impl(name);//获取类对象
    if (result) return result;

    // Try Swift-mangled equivalent of the given name.
    if (char *swName = copySwiftV1MangledName(name)) {
        result = getClass_impl(swName);
        free(swName);
        return result;
    }

    return nil;
}

我们可以看出,objc_getClass方法传入一个类名,返回的是class对象,无法获取meta-class对象

相关文章

网友评论

    本文标题:Objective - C 对象的本质(三)对象的分类

    本文链接:https://www.haomeiwen.com/subject/hbkwihtx.html