我是靠谱客的博主 完美自行车,最近开发中收集的这篇文章主要介绍【iOS】通过OC类的本质初探OC方法调用,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

OC对象的分类

OC对象主要分为三种

  • instance对象(实例对象)
  • class对象(类对象)
  • meta-class对象(元类对象)

instance对象

instance对象就是通过类alloc出来的对象,每次调用alloc都会产生新的instance对象

// object1、object2是NSObject的instance对象(实例对象)
NSObject *object1 = [[NSObject alloc] init];
NSObject *object2 = [[NSObject alloc] init];

// 通过打印可以看出,它们是不同的两个对象,分别占据着两块不同的内存
NSLog(@"instance - %p %p",
	    object1,
	    object2);

instance对象在内存中存储的信息

  • isa指针
  • 其他成员变量的具体值
    instance

class对象

每个类在内存中有且只有一个class对象

Class objectClass1 = [object1 class];
Class objectClass2 = [object2 class];
Class objectClass3 = object_getClass(object1);
Class objectClass4 = object_getClass(object2);
Class objectClass5 = [NSObject class];

// 通过打印可以看出,上面几个方法返回的都是同一个类对象,内存地址都一样
NSLog(@"class - %p %p %p %p %p %d",
		objectClass1,
		objectClass2,
		objectClass3,
		objectClass4,
		objectClass5);

注意: class方法返回的一直是类对象,所以哪怕这样写还是会返回类对象

Class objectMetaClass2 = [[[NSObject class] class] class];

class对象在内存中存储的信息

  • isa指针
  • superclass指针
  • 类的属性信息(@property)、类的对象方法信息(instance method)
  • 类的协议信息(protocol)、类的成员变量信息(ivar)

class

meta-class对象

objectMetaClass是NSObject的meta-class对象(元类对象),每个类在内存中有且只有一个meta-class对象

Class objectMetaClass = object_getClass(objectClass5);

meta-class对象和class对象的内存结构是一样的,但是用途不一样,在内存中存储的信息主要包括

  • isa指针
  • superclass指针
  • 类的类方法信息(class method)

meta-class

使用class_isMetaClass(Class _Nullable cls)来查看Class是否为meta-class 的方法

NSLog(@"objectMetaClass - %p %d", objectMetaClass, class_isMetaClass(objectMetaClass));

注:meta-class对象和class对象的内存结构是一样的,以上两者相比对方没有列出的信息对应的值其实是null

isa和superclass

OC instance class meta-class isa superclass

这里有一个经典的图,精辟描述了 实例对象、类对象、元类对象、isa、superclass 之间的关系

instance通过isa找到class, class通过isa找到meta-class, 所有meta-class的isa都指向 基类的meta-class, 而基类的meta-class的 isa 指向自己

子类的 superclass 指向父类, 直到基类(NSObject),而基类的 superclass 指向nil
子类的元类的 superclass 指向父类的元类, 直到基类(NSObject)的元类, 而基类的元类的 superclass 指向 基类

Tip:

所以如果调用一个基类没有实现的类方法,即基类的元类中没有存储该类方法, 会去基类中找方法名一致的对象方法

OC是面向对象的 对象调用方法 就等于 给对象发送消息 objc_msgSend中传入的是方法名, 没有带上 + - 符号

//消息由接受者,selector及参数构成。给某对象“发送消息”也就相当于在该对象上调用方法。

id returnValue = objc_msgSend(someObject,@selector(messageName:),parameter);

总结如下:

每个类的实例对象、类对象、元类对象都有一个isa指针

  • instance的isa指向class
    • 当调用对象方法时,通过instance的isa找到class,最后找到对象方法的实现进行调用
  • class的isa指向meta-class
    • 当调用类方法时,通过class的isa找到meta-class,最后找到类方法的实现进行调用
  • meta-class的isa指向基类的meta-class

每个类的类对象、元类对象都有一个superclass指针

  • class的superclass指针指向父类的class
    • 如果没有父类,superclass指针为nil
  • meta-class的superclass指向父类的meta-class
    • 基类的meta-class的superclass指向基类的class

instance调用对象方法的轨迹

  • isa找到class,方法不存在,就通过superclass找父类

class调用类方法的轨迹

  • isa找meta-class,方法不存在,就通过superclass找父类

最后

以上就是完美自行车为你收集整理的【iOS】通过OC类的本质初探OC方法调用的全部内容,希望文章能够帮你解决【iOS】通过OC类的本质初探OC方法调用所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部