1-1、什么是类

面向对象编程中,最重要的概念就是类,那么什么是类?如下:

在OC源码中,关于类的定义:

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

# if !**OBJC2**
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

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

# endif

} OBJC2_UNAVAILABLE; 
/* Use `Class` instead of `struct objc_class *` */ 

对象的定义:

/// Represents an instance of a class.
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

泛型的定义:

/// A pointer to an instance of a class.
typedef struct objc_object *id;
  • struct objc_classs结构体里存放的数据称为元数据metadata,通过成员变量的名称我们可知里面存放有指向父类的指针类的名字版本实例大小实例变量列表方法列表缓存遵守的协议列表等,这些信息就足够创建一个实例了。

  • 通过对比,struct objc_classs结构体 和 struct objc_object结构体,struct objc_classs结构体的第一个成员变量也是isa指针,这就说明了Class本身其实也是一个 对象,称之为类对象

  • 类对象在编译期产生,用于创建实例对象,是单例。即任何 本身也是个对象,称为 类对象

  • 在OC中,每当我们创建一个类,在编译时就会创建一个元类,而这个元类的对象就是我们创建的这个类

  • 类对象中的元数据存储的都是如何创建一个实例的相关信息,那么类对象和类方法应该从哪里创建呢?就是从isa指针指向的结构体创建,类对象的isa指针指向的我们称之为元类(metaclass),元类中保存了创建类对象以及类方法所需的所有信息,因此整个结构应该如下图所示:
20180507111819102.png

iOS class深入理解: 实例对象、类对象、元类和isa指针

通过上图我们可以清晰的看出来一个实例对象也就是struct objc_object结构体它的isa指针指向类对象,类对象的isa指针指向了元类,super_class指针指向了父类的类对象,而元类的super_class指针指向了父类的元类,那元类的isa指针又指向了什么?为了更清晰的表达直接使用一个大神画的图。


截屏2021-04-21 下午2.28.17.png

iOS class深入理解: 实例对象、类对象、元类和isa指针

通过上图我们可以看出整个体系构成了一个自闭环,如果是从NSObject中继承而来的上图中的Root class就是NSObject。至此,整个实例、类对象、元类的概念也就讲清了,接下来我们在代码中看看这些概念该怎么应用。

类对象
有如下代码

@interface Person : NSObject

@property (nonatomic, copy) NSString* name; 
@property (nonatomic, assign) NSUInteger age;

@end

@implementation Person

@synthesize name = _name; 
@synthesize age = _age;

@end

int main(int argc, const char * argv[]) { 
@autoreleasepool { 
Person *p = [[Person alloc] init]; 
Class c1 = [p class]; 
Class c2 = [Person class]; 
//输出 1 
NSLog(@”%d”, c1 == c2); 
} 
return 0; 
} 
  • c1是通过一个实例对象获取的Class,实例对象可以获取到其类对象,类名作为消息的接受者时代表的是类对象,因此类对象获取Class得到的是其本身,同时也印证了类对象是一个单例的想法。
    那么如果我们想获取isa指针的指向对象呢?

介绍两个函数

OBJC_EXPORT BOOL class_isMetaClass(Class cls) 
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
OBJC_EXPORT Class object_getClass(id obj) 
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); 

class_isMetaClass用于判断Class对象是否为元类,
object_getClass用于获取对象的isa指针指向的对象。

再看如下代码:

int main(int argc, const char * argv[]) { 
@autoreleasepool { 
Person *p = [[Person alloc] init]; 
//输出1 
NSLog(@”%d”, [p class] == object_getClass(p)); 
//输出0 
NSLog(@”%d”, class_isMetaClass(object_getClass(p))); 
//输出1 
NSLog(@”%d”, class_isMetaClass(object_getClass([Person class]))); 
//输出0 
NSLog(@”%d”, object_getClass(p) == object_getClass([Person class])); 
} 
return 0; 
} 

通过代码可以看出,一个实例对象通过class方法获取的Class就是它的isa指针指向的类对象,而类对象不是元类,类对象的isa指针指向的对象是元类。

1、在Objective-C中,任何类,它自身也是对象。

2、Objective-C类是由Class类型来表示的,它实际上是一个指向objc_class结构体的指针;

3、对象的结构体中,只有一个指向其类的isa指针;

4、isa:是一个Class类型的指针;

  • 每个实例对象也有个isa指针,指向自身类;

  • 每个类也有个isa指针,指向meta-class(元类);

  • meta-classisa指向其基类的meta-class,以此作为它们的所属类。

  • 任何NSObject继承体系下的meta-class都使用NSObject的meta-class作为自己的所属类,而基类的meta-classisa指针是指向它自己。这样就形成了一个完美的闭环。

  • isa作用:当一个对象收到一条消息时,runtime会根据isa指针找到能够响应这个消息的对象,然后在该对象所属类的方法列表中查找消息对应的selector指向的方法,若没有找到对应的方法,meta-class会向父类查找方法。找到后即运行这个方法。

5、super_class:指向该类父类的Class类型指针。如果该类已经是最顶层的父类,则super_classNULL

6、ivars:成员变量的数组

7、cache:用于缓存最近调用的方法。提高调用效率。

8、version:类的版本信息,默认为0。
————————————————
版权声明:本文为CSDN博主「HANXIUHUI」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41463971/article/details/86672815
转载出处:http://blog.csdn.net/u014205968/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容