深入学习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信息来判断的。

通过分析,我们可以发现类其实也是一个对象。当我们定义一个类的时候,实际上定义了两个类,一个类是我们看得到的类,一个类是我们看不到的同名元类,而我们看到的类就是该元类的对象。(具体可看看之前提到的那篇文章)

(没思路,理清了再来补充)

时间: 2024-12-16 04:14:55

深入学习Objective-C的NSObject的相关文章

Windows下搭建objective C开发环境

最近打算针对iPhone.iPod touch和iPad开发一些应用,所以,需要开始学习Objective C(苹果推出的类似C语言的开发语言).由于苹果的自我封闭的产业链发展模式(从芯片.机器.开发语言.终端产品.服务)的限制,要想开发针对苹果 iPhone等产品的应用程序,就需要用Mac机器,在Xcode的IDE上使用Objective C语言开发.Mac机器就不用说了,那比PC机器要贵不少(当然性价比还是很高的),所以,要想廉价方式学习Objective C就必须要在Windows上能搭建

Windows在结构objective C开发环境

对于近期打算iPhone.iPod touch和iPad开发一些应用程序,所以.需要开始学习Objective C(苹果推出的类似C语言的开发语言).因为苹果的自我封闭的产业链发展模式(从芯片.机器.开发语言.终端产品.服务)的限制,要想开发针对苹果 iPhone等产品的应用程序,就须要用Mac机器,在Xcode的IDE上使用Objective C语言开发. Mac机器就不用说了.那比PC机器要贵不少(当然性价比还是非常高的),所以,要想便宜方式学习Objective C就必须要在Windows

iOS Cookie学习(NSHTTPCookieStorage的使用)

最近也是忙里偷闲,无意中发现了一位大牛的文章,小小的研究了一下HTTP.今天先写一点Cookie,之前有过文章都是关于Cookie的,也没有深入研究,今天也算是一起学习吧. @interface FQWebGlobalCookies : NSObject /* 全局单例 */ + (id)globalCookiesManager; /* 对每份URL产生的Cookie 保存起来,以便管理 对响应头域中的cookie进行保存 */ - (void)storeResponseCookies:(NSD

程序员学习编程需要攻克的8个障碍

大多数学习者同样碰到过相同的障碍,但是,一旦克服了这些壁垒,那么好处立马就来: 更享受学习经历 进步更快 碰到难题更执着,不轻言放弃 写代码时更独立 那么,这些障碍究竟是什么呢,我们又该如何攻克它们? 1.不正确的学习动机 在谈及壁垒之前,我想先着重说明学习动机的重要性.不要只是为了编程而学编程,也不要因为听说它很酷,很划得来就来学编程. 你得因为要解决问题而学习编程,你得因为想要自动化和改善生活而学习编程,你得因为想要构建应用程序以造福社会来学习编程. 如果你只是喜欢编程,并希望以此作为职业的

CBCentralManager学习笔记

// CBCentralManager学习笔记 @interface CBCentralManager : NSObject //CBCentralManager的几种状态 typedef NS_ENUM(NSInteger, CBCentralManagerState) { // 初始的时候是未知的(刚刚创建的时候) CBCentralManagerStateUnknown = 0, //正在重置状态 CBCentralManagerStateResetting, //设备不支持的状态 CBC

Object-c 学习笔记(一)

想做IOS开发,培训之前自己先自学一段时间,于是开一篇新的笔记来记录学习的点滴吧. Objective-c是以c语言为基础的扩展集,当然首先要得熟悉c语言再去学习Objective-c,我是根据<Objective-c基础教程>来自学的.鄙人初学,如有观点不同或者错误之处请指正亦可贻笑大方. 构建Objective-c程序 我们需要先下载Xcode来作为基本的编辑器,下载安装完成后我们来新建一个Xcode Project,之后我们选择 要在Type中选择Foundation,然后选择Next,

NativeScript官方书籍:1.为什么选择nativescript

1.为什么选择nativescript 本章介绍 什么是NativeScript nativescript对于移动开发世界意味着什么 NativeScript工作原理 在早期的移动应用程序(前iPhone)中,在一次编码多平台部署方法论上,没有过多笔墨.开发人员只是想尽快将应用程序发布到到苹果或谷歌商店里.如果这意味着他们的应用程序不支持这两个平台,也是一个合理的牺牲资源的理由. 及至今日:移动世界在不断变化,使得跟上最新设备越来越困难.当开发人员创建应用程序时,他们需要接触到尽可能多的受众:仅

前传——一个文科生转行做编程的参考样本

动笔                                                                                                                                                                                      听闻前辈讲述写博客的诸多好处,早有开始写「技术博客」的想法,但囿于自身浅薄的「技术」,以及轻微的强迫症——总想准备充分后下笔——比如

GnuStep使用

gcc -o main main1.m -I/GNUstep/System/Library/Headers -fconstant-string-class=NSConstantString -L/GNUstep/System/Library/Libraries -lobjc -lgnustep-base 1.cd /home 2.gcc -o helloworld helloworld.m -I/GNUstep/System/Library/Headers -fconstant-string-c

十佳最受欢迎的编程语言,你擅长几个?

保持领先是任何软件工程师面临的最大挑战之一.那么哪种编程语言的需求最经久不衰? 10. ASP.NET ASP.NET是服务器端的Web应用程序框架语言,目的是为Web开发制作设计动态网页.它是由微软开发的,该语言允许程序员构建动态的web站点,web应用程序和web服务.2002年1月首次发布的.NET Framework1.0版本,是对微软的动态网页技术(ASP)的继承和扩展.ASP.NET建立在公共语言运行时(CLR)的基础上,且程序员可以使用任何支持.NET语言编写ASP.NET代码.