OC对象的本质(上):OC对象的底层实现原理
OC对象的本质(中):OC对象的种类
OC对象的本质(下):详解isa&superclass指针
Objective-C中的对象,简称OC对象,主要分3类
-
instance
对象(实例对象) -
class
对象(类对象) -
meta-class
对象(元类对象)
instance 实例对象
instance
对象就是通过alloc
方法创建出来的对象,每次调用alloc
方法都会生成新的instance对象
NSObjcet *object1 = [[NSObject alloc] init];
NSObjcet *object2 = [[NSObject alloc] init];
上面的object1
object2
都是NSObject的instance对象(实例对象),因为他们都有自己的独有内存,所以是两个不同的对象
instance
对象在内存中存放的信息包括
-
isa
指针(因为基本上我们常用的类以及自定义类都继承自NSObject
,所以我们这里讨论的instance
里面都包含isa
指针) - 其他
成员变量
class 类对象
class
对象的作用是用来描述一个instance
对象,它内部存放一个类的属性信息(@property
)、对象方法信息(instance method
)、协议信息(protocol
)、成员变量信息(ivar
),另外class对象里面还有两个指针,isa
指针 和superclass
指针。
可以通过一下方法,获取一个类的类对象
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
Class objClass1 = [NSObject class];
Class objClass2 = [obj1 class];
Class objClass3 = [obj2 class];
Class objClass4 = object_getClass(obj1);
Class objClass5 = object_getClass(obj2);
//一个类在内存中只存一份
NSLog(@"\nobjClass1:%p\nobjClass2:%p\nobjClass3:%p\nobjClass4:%p\nobjClass5:%p",
objClass1,
objClass2,
objClass3,
objClass4,
objClass5);
}
return 0;
}
如上图打印结果,可以看出,一个类的类对象是唯一的,在内存中只存一份,这也很好理解,因为类对象中的信息只需要一份就够了。
meta-class 元类对象
meta-class
对象的作用是用来描述一个class
对象。跟class
一样,元类对象在内存中也是只有一份的。它内部存储了isa
指针 +superclass
指针 + 类方法信息(+方法)
下面是元类对象一些相关的api:
-
object_getClass(<class对象>);
获取元类对象,参数为一个类对象 -
class_isMetaClass(<class对象/meta-class对象>);
判断是否是元类对象
因为class
和meta-class
对象都可以通过object_getClass
获得,因此他们的类型都是一样的,都是typedef struct objc_class *Class
这个Class
类,可以理解,它们各自利用Class
的一些成员变量来实现自己的功能。
几个常用方法的区别
(a)
Class objc_getClass(const char *aClassName)
- 入参是一个字符串,也就是类名
- 返回值是对应的
class对象
- 因为我们通过字符串,只能定义类的名字,所以这个方法只能返回
class对象
(b)
Class object_getClass(id obj)
- 入参
obj
可以是instance对象
、class对象
或者meta-class对象
- 返回值
- 传入
instance对象
,返回对应的class对象
- 传入
class对象
,返回对应的meta-class对象
- 传入
meta-class对象
,返回NSObject(基类)
的meta-class对象
- 传入
/***********************************************************************
* object_getClass.
* Locking: None. If you add locking, tell gdb (rdar://7516456).
**********************************************************************/
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
根据上面的object_getClass
的源码实现,我们看到,这个方法返回的是isa
指针。
我用仅有的一点美术功底,手绘描述了一下各种isa
间的关系,所以根据instance
的isa
可以得到它的class
对象,根据class
的isa
指针,可以得到它的meta-class
对象,至于meta-class的
isa`指针问题,我们留到下一章仔细论述。
(c)
- (Class)class
&+ (Class)class
一个类的实例方法和类方法里面都有这个方法。我们用代码来测试一下
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSObject *obj1 = [[NSObject alloc] init];
Class objClass1 = [NSObject class];
Class objClass2 = [obj1 class];
Class objClass3 = [objClass1 class];
Class objClass4 = [objClass2 class];
//一个类在内存中只存一份
NSLog(@"\nobjClass1:%p\nobjClass2:%p\nobjClass3:%p\nobjClass4:%p",
objClass1,
objClass2,
objClass3,
objClass4);
}
return 0;
}
输出结果如下
根据结果,我们可以总结出,一个
class对象
调用(Class)class
方法,返回的不是它的meta-class对象
,而是它自身。总之,不论- (Class)class
还是 + (Class)class
,都只能返回一个类的`class对象
OC对象的本质(上):OC对象的底层实现
OC对象的本质(中):OC对象的分类
OC对象的本质(下):详解isa&superclass指针