OC类与对象上半章节较为重要的部分

OC类与对象上半章节较为重要的部分

前言

分享会的时候对于isKindOfClass和isMemberOfClass两者的区别不了解,所以写了这篇博客来记录上次的遗漏点。

OC对象的本质

首先我们都知道OC是一门面向对象语言编程,但是它是基于C\C++这两门语言实现的,所以OC的对象.类主要是基于结构体去实现的。

每当我们谈及OC对象的时候,我们就不得不说一下NSObject,所有的OC对象都继承自NSObject,上面也说了对象,类主要是基于结构体去实现的,那么这个结构体里到底有什么呢。

struct NSObject_IMPL {
	Class isa; //Class是一个结构体类型,isa是一个结构体指针
};
  • 继承自NSObject的对象结构大致是,这是一个继承自NSObject的对象Student(被添加了name和age两个属性)
struct Student_IMPL {
	struct NSObject_IMPL NSObject_IVARS;Class isa;)
	int _age;
	NSString *_name;
};
  • 即第一个元素是isa指针,我们可以认为isa的地址即是Student的地址,后面的成员变量会遵循内存对齐的原则逐一分配内存地址。

OC的实例对象,类对象,元类对象

OC主要包括了三种对象

  1. 实例对象
  2. 类对象
  3. 元类对象
  1. 实例对象就是通过类alloc出来的对象,每一次调用alloc都会产生一个新的instance对象。
  1. isa 指针
  2. 其他成员变量
@interface Student : NSObject
@property(nonatomic,strong)NSString * name;
@property(nonatomic,assign)int age;
@end

那么它就是如下的一个存储方式

请添加图片描述

  1. 类对象(class)

通过实例对象的class方法获取道这个实例的类对象,每个类在内存中有且只有一个class对象

  1. isa指针
  2. superclass指针
  3. 类的属性信息(@property)
  4. 类的对象方法信息(instance method)
  5. 类的协议信息(protocol)
  6. 类的成员变量信息(ivar)

他的内存信息是这样的
请添加图片描述

  1. 元类对象

笔者对于Runtime部分没有学习,但是记住每个类在内存中有且只有一个meta-class对象,

  1. isa指针
  2. superclass指针
  3. 类的类方法信息(class method)

isa和superclass分析

上面发现了一个事情就是实例对象内存里没有包含对象方法,实例对象怎么调用对象方法?类对象也没有类方法的信息,但是却可以通过类名调用类方法?子类如何调用父类的方法

  1. 实例对象的isa指向类对象
  2. 类对象的isa指向元类对象
  3. superclass指针只会存在类对象和元类对象中,每个类(元类)对象的superclass指针都是指向它的父类,

这里可以用一张非常经典的图片进行一个总结。

请添加图片描述

分析isKindOfClass和isMemberOfClass方法

当类调用 + (BOOL)isKindOfClass: (class)cls的时候,我们会从它的元类开始向上寻找,然后找他的元类的父类,知道找到根元类,然后在找到NSObject,

当元类调用+ (BOOL) isKindOfClass,同样是直接找到他的根元类,然后在找到他的根子类(NSObject).

当对象调用 - (BOOL) isKindOfClass:,这个函数则是从他的类开始向父类一直往上寻找直到找到NSObject为止。

而isMemberofClass函数则是仅仅包括了isKindOfClass函数的第一步,仅仅只比较isa指针是否指向后面的那一个元类或者是一个根元类这一个步骤。

总结isKindOfClass: (class)cls的几种情况

  • 类调用 + (BOOL)isKindOfClass: (class)cls

    • cls除了是[NSObject class]之外都报错
  • 元类调用的时候+ (BOOL)isKindOfClass: (class)cls

    • 判断cls是不是 根元类->NSObject 中的任意一个
  • 对象调用的时候则是判断

    • cls是不是 **类对象->父类->…->NSObject **(superclass继承链)其中一个

总结isMemeberOfClass:Class(cls)的几种情况

我们都是主要判断他的isa和cls相同

->和点语法的区别

  1. ->这个方式的访问是直接调用所指向的一个内存,这样子更快,而点语法实际上是调用他的setter语句和getter语句,这个语句调用的速度更慢
  2. 需要注意的是使用点语法访问属性的时候可以直接用“.”+属性名,而使用“->"访问属性的时候则不能省略成员变量名前的下划线“_”否则会报错。
  3. 我们一般不采用->的方式访问成员变量,但是成员变量默认受保护,所以常常报错。

self在类方法里指向的是(调用当前类方法的)类

self在对象方法中,self指的是对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值