首页 > 代码库 > 深入学习Objective-C的NSObject
深入学习Objective-C的NSObject
先来看看NSObject的主要定义如下所示(包括一些我的理解注释):
@interface NSObject <NSObject> { Class isa OBJC_ISA_AVAILABILITY; } /* Initializing a Class */ /** * @author Arbboter, 15-01-15 22:01:47 * * 如果当前类或者分类实现了load方法才会调用该方法,否则调用父类的方法。 * 是么时候调用该方法:当类或者其分类在静态链接或者动态加载的时候调用该方法 * 因此,当import类的头文件的时候,会调用load方法 */ + (void)load; /** * @author Arbboter, 15-01-15 22:01:37 * * 在runtime时第一次调用类的方法(实例方法或者类方法,不包括load方法) * 前会调用该方法,而且显示调用层次是从父类到子类(这一点和对象的初始化一致)。 * 如果子类没有实现该方法,会直接调用父类的,需要注意的是,如果有继承层次为: * class_1 <- class_2 <- class_3 * 而只有class_1实现了该方法,那么创建一个clsaa_3的对象的时候,会调用该方法 * 三次(每一层类都会调用该方法),且都是class_1实现的方法 */ + (void)initialize; /* Creating, Copying, and Deallocating Objects */ /** * @author Arbboter, 15-01-15 22:01:57 * 创建一个当前类的实例变量所需的内存 * @param zone 已经忽略 * @return 分配的对象 */ + (instancetype)allocWithZone:(struct _NSZone *)zone; /** * @author Arbboter, 15-01-15 23:01:06 * 由于历史问题,该方法会调用allocWithZone方法创建对象内存 * @return 分配了内存的对象 */ + (instancetype)alloc; /** * 初始化对象的isa为描述类的数据结构,其他的实例变量为0 */ - (instancetype)init; /** * @author Arbboter, 15-01-15 23:01:57 * 相当于 [[类名 alloc] init] * @return 初始化好的对象 */ + (instancetype)new; /** * @author Arbboter, 15-01-15 23:01:49 * 由NSCopying协议定义的copyWithZone:方法返回的对象 * @return copy出的对象 */ - (id)copy; /** * @author Arbboter, 15-01-15 23:01:49 * 由NSMutableCopying协议定义的mutableCopyWithZone:方法返回的对象 * @return copy出的对象 */ - (id)mutableCopy; /** copy协议 */ + (id)copyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE; + (id)mutableCopyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE; /** 释放销毁对象 */ - (void)dealloc; /** 其他的方法这里不予讨论了 */ @end
首先需要注意的两个方法是load和initialize的调用次序和时机。load是当类的头文件或者其扩展被import的时候就会调用,不管有没有使用该类,而initialize是在类的方法被第一次调用前会被调用。更多的细节问题比较烦,代码中的注释相对二样更详尽一点。
接下来来看看NSObject的一个唯一成员变量isa,该变量的类型是Class。通过查看Class的定义以及相关的类型定义,你会发现一个很有趣的事实,如下所示:
/** Objective-C对象的定义 */ @interface NSObject <NSObject> { /** 指向当前类的实例所在的类的一个指针 */ Class isa OBJC_ISA_AVAILABILITY; } /* 一些方法的定义 */ @end /** Objective-C对象的结构体的定义 * 用于保存对象的状态(实例变量) */ struct objc_object { Class isa OBJC_ISA_AVAILABILITY; }; /** Objective-C对象的类的定义 * 用于保存对象的方法 */ struct objc_class { Class isa OBJC_ISA_AVAILABILITY; /** 以下省略了oc1.0版本定义的部分 */ } OBJC2_UNAVAILABLE; typedef struct objc_class *Class; // 指向类结构的指针 typedef struct objc_object *id; // 指向Objective-C对象结构体的指针从上面的定义我们发现了之前所提到的Class和我们熟悉的id的定义,同时发现了一个奇怪的现象。结构体objc_object、objc_class和NSObject的成员变量居然一模一样,都是
Class isa OBJC_ISA_AVAILABILITY;
这是为什么呢?大家可以看看《Objective-C的对象模型分析》这篇文章,然后再回头看这个问题或许就能看出一些名堂了。其实NSObeject是Objective-C的几乎全部对象的基类,该类定义了类的状态信息(变量)和方法(类方法和实例方法),而Class是用于指向保存NSObeject的方法信息的指针,id用于保存NSObject的状态信息的指针,两个一起协作一起更好地描述NSObject。每个Objective-C的对象的成员变量isa指向的是这个对象的类信息,同时isMemberOfClass:方法就就是根据isa信息来判断的。
通过分析,我们可以发现类其实也是一个对象。当我们定义一个类的时候,实际上定义了两个类,一个类是我们看得到的类,一个类是我们看不到的同名元类,而我们看到的类就是该元类的对象。(具体可看看之前提到的那篇文章)
(没思路,理清了再来补充)
深入学习Objective-C的NSObject
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。