@MicroCai
2016-05-20T12:10:43.000000Z
字数 2219
阅读 6055
Archives
iOS
《Effective Objective-C Notes》系列博文整理自《Effective Objective-C 2.0》
每个 Objective-C 对象都是指向某块内存数据的指针,所以在声明变量时,类型后面要跟一个“*”字符:
NSString *pointerVariable = @"someString";
pointerVariable
是栈上的一个指针变量,@"someString"
是堆上的内存对象,pointerVariable
变量内存放着堆上对象的内存地址。如果想把 Objective-C 对象分配在栈上:
NSString pointerVariable = @"someString";
编译器就会报错:
"Interface type cannot be statically allocated"
而对于通用对象类型 id,由于其本身已经是指针类型,所以可以这样写:
id genericTypeString = @"someString";
id 对象的定义如下:
typedef struct objc_object {
Class isa;
} *id;
由此可见,每个对象结构体的首个成员是 Class 类的变量,通常被称为“is a”指针,顾名思义,表示“是一个”的含义。如前面例子所用的对象就可以翻译成“is a NSString”,即“我是一个 NSString 类型的对象”。那么 Class 是什么呢?
typedef struct objc_class *Class;
struct objc_class {
Class isa; //指向对象类型
Class super_class; //指向父类的
const char *name; //类名
long version; //类的版本信息,默认为0
long info; //供运行期使用的一些位标识。
long instance_size; //类的实例变量大小
struct objc_ivar_list *ivars; //成员变量的数组
struct objc_method_list **methodList; //方法定义的数组,注意这里是“**”
struct objc_cache; //指向最近使用的方法,用于方法调用的优化.
struct objc_protocol_list *protocols; //协议的数组
}
结构体的内容捡几个再加以说明下
methodList:这是方法的定义列表,是指针的指针,所以可以通过修改该指针指向的指针的地址,来动态增加方法,这也是 Category 的实现原理。同理存储对象成员变量的指针是 *vars,所以无法动态增加成员变量。所以 Category 只能添加方法,却不可添加属性的原因就在于此了。那苹果什么要这么设计呢?简单说 Category 设计的目的就是用来扩展类功能,而非封装数据,所有的属性和成员变量应该放在主接口(main interface),才能使得类的设计更加清晰。
objc_cache:在讲解 Effective Objective-C Notes:理解消息传递机制,会发现 Objective-C 要调用一个方法似乎要经过很多步骤。为了优化方法调用速度,就将调用过的一些方法缓存到到 objc_cache 中,后续如果再次调用时,会先从缓存列表里面查找,如此速度便可加快。
此结构体存放类的 元数据(metadata),例如类的实例实现了几个方法,具备了多少个实例变量等信息。结构体的首个变量也是 isa 指针,说明 Class 本身也是 Objective-C 对象。对象所属的类型(即 isa 指针所指向的对象类型)是另一个类,叫做 元类(metaclass),用来表述对象本身所具备的元数据。类方法就定义在此处,因为这些方法可以理解成类对象的实例方法。每个类仅有一个类对象,每个类对象也仅有一个与之相关的元类。
假设有个名为 SomeClass 的子类从 NSObject 中继承而来,则其继承体系如下:
小知识:“元(meta)”是什么
很多童鞋在了解 NSObject 或 runtime 时,经常会碰到“元”这个词,比如“元类”、“元数据”等等,那么这里的“元”到底是什么意思?
其实这就是个英语问题,元就是 meta,对元的理解其实就是对 meta 的理解。那么 meta 是啥?meta 在英语里并不是单字,通常会和后面的词连接起来,用以描述后面的词,表示“关于...的...”,这么说很抽象。举个例子,比如 meta-data 就是“关于数据的数据”,即这个数据大小、类型等用来描述数据的数据信息,再比如 meta-language 就是“关于语言的语言”,meta-class,就是这个类的类。
这么说应该能明白吧,这也从另一方面说明学好英语对于学好计算机是有多么的重要。
尾声:这篇博文的内容不多,大家看了之后可能还回去看 NSObject 的实现等等,在下面关于 NSObject 的实现我给大家摘录了一些写的不错的博文,供大家学习。另外如果童鞋们是直接看源码的话,从 这里下载 后,搜索 Object.m
文件,即可找到很多方法的实现代码。
相关阅读推荐
[1] Apple Open Source Runtime Code
[2] 唐巧的技术博客:Objective-C对象模型及应用
[3] 深入学习Objective-C(一):揭开NSObject的面纱(作者的行文好逗哈哈哈)
[4] uxyheaven:Objective-C NSObject 的实现分析