为了了解其中的原理,我做了些实验,本文只单单记录下关于extension的部分。如后续有时间再更新category的部分和两者的完整对比。
进入正题,extension,中文译为类扩展或延展,网上一般说它是用来将类的方法私有化的一种解决方案。为了验证它如何实现此功能,我做了如下实验:
实验一:将类的声明、类扩展的声明、类的实现全部放在类的.h文件中。
实验结果:在外部可以直接访问类扩展中添加的属性和方法。
备注:此时写类扩展与直接将扩展方法和属性添加在源声明中效果完全相同,类扩展并不能起到属性和方法私有化的作用。
实验二:按一般的写法,将类的声明写在源h文件中,将类扩展和实现写在源m文件中。在外部引用源h文件。
实验结果:在外部不可以直接访问类扩展中添加的方法和属性,但可以使用proform之类的方法进行访问。
备注:此时实现了方法和属性的私有化。
然而:我进行了一下尝试,如果在外部引用的不是源h文件,而是源m文件。。。则外部可以直接访问类扩展中添加的方法和属性,并不能实现私有化。
实验三:将类扩展的声明加在非源h文件和非源m文件的其他文件(称为extern文件)中,而在源h和源m文件中不引用该文件。
实验结果:生成的类中并没有类扩展中添加的属性和方法。外部的类如果引用了extern文件,在coding和编译时,如果使用了类扩展中声明的方法和属性均不会报错,而在运行时出错。
实验四:接实验三,在源m文件中引入extern文件(由于extern文件声明了源h中类的类扩展,所以在源h文件中不能引用extern文件)
实验结果:生成的类中有类扩展中声明的属性和方法,外部如果引用了extern文件则可以直接访问类扩展中声明的方法和属性。
总结:externsion的语法仅仅相当于将类的原始声明部分拆分成几块。类扩展中的声明与源h文件中写的声明完全等同,都可以声明属性,方法,成员变量。
编译器在编译完类的源h和源m文件后,类的成员和方法都确定了,再在其地方声明类扩展无效,但如果在源m文件中引入了类扩展的声明文件,则在编译该类的过程中就知道了该类的扩展属性和方法,扩展有效。
网上流传的类扩展可以实现属性和方法的私有化的说法只是使用类扩展可以达到的一种效果,与类扩展本身并无关系。由于外部一般只能看见h文件中声明的方法和属性,而无法引用到在m文件中声明的方法和属性(因为无法引到m文件或者是一般不引m文件),所以给人以方法和属性被私有化的感觉,只要能想办法引到类扩展中声明的部分,就可以直接访问其中声明的方法和属性,即使不能引到,只要能绕过编译器的检查,同样可以使用扩展属性和方法。
extension,基本理解完成,后续补充category的理解。