oc——类——数据成员
2017-03-14 16:24
78 查看
数据成员
类只有instance object数据成员,没有class object数据成员,因此数据成员存储在class object(非meta-class object)的ivars中struct objc_ivar { char *ivar_name OBJC2_UNAVAILABLE; char *ivar_type OBJC2_UNAVAILABLE; int ivar_offset OBJC2_UNAVAILABLE; #ifdef __LP64__ int space OBJC2_UNAVAILABLE; #endif } OBJC2_UNAVAILABLE; struct objc_ivar_list { int ivar_count OBJC2_UNAVAILABLE; #ifdef __LP64__ int space OBJC2_UNAVAILABLE; #endif /* variable length structure */ struct objc_ivar ivar_list[1] OBJC2_UNAVAILABLE; } OBJC2_UNAVAILABLE; /// An opaque type that represents an instance variable. typedef struct objc_ivar *Ivar; struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
分析:
数据成员结构为objc_ivar,objc_ivar保存着数据成员名(ivar_name),数据成员类型(ivar_type,即数据成员字长),数据成员相对于instance object首地址offset(ivar_offset)和数据成员内存对齐(space),数据成员名唯一确定数据成员
ivars是class object的数据成员list,因此同一class object中,数据成员名不能重名,否则编译器不能确定使用哪个数据成员,二义性错误,或者list中优先search到的数据成员名屏蔽list中之后重名数据成员(ignore之后重名数据成员),oc在编译期避免此情况发生
@interface FBAnimal : NSObject { @public int _food1; } @end @interface FBAnimal () { @public int _food2; } @end @implementation FBAnimal { @public int _food3; } @end
注:_food1,_food2,_food3不能重名
继承体系的数据成员
理论上子类数据成员和父类数据成员相互独立,互不影响,因为数据成员分处于不同的class object中,但在实际中,还是有所限制@interface FBAnimal : NSObject { @public int _food1; } @end @interface FBAnimal () { @public int _food2; } @end @implementation FBAnimal { @public int _food3; } @end
@interface FBFood : NSObject
@end
@implementation FBFood
@end
primary class interface
@interface FBDog : FBAnimal { @public //FBFood *_food1; //FBFood *_food2; //FBFood *_food3; } @end @interface FBDog () @end @implementation FBDog @end void member_access() { FBFood *food = [[FBFood alloc] init]; FBAnimal *animal1 = [[FBAnimal alloc] init]; FBAnimal *animal2 = [[FBDog alloc] init]; FBDog *dog = [[FBDog alloc] init]; animal1->_food1 = 5; animal1->_food2 = 5; animal1->_food3 = 5; animal2->_food1 = 5; animal2->_food2 = 5; animal2->_food3 = 5; dog->_food1 = 5; dog->_food2 = 5; dog->_food3 = 5; }
注:FBDog的_food1,_food2,_food3与FBAnimal的_food1,_food2,_food3重名,编译error
extension
@interface FBDog : FBAnimal @end @interface FBDog () { @public FBFood *_food1; FBFood *_food2; FBFood *_food3; } @end @implementation FBDog @end void member_access() { FBFood *food = [[FBFood alloc] init]; FBAnimal *animal1 = [[FBAnimal alloc] init]; FBAnimal *animal2 = [[FBDog alloc] init]; FBDog *dog = [[FBDog alloc] init]; animal1->_food1 = 5; animal1->_food2 = 5; animal1->_food3 = 5; animal2->_food1 = 5; animal2->_food2 = 5; animal2->_food3 = 5; dog->_food1 = food; dog->_food2 = food; dog->_food3 = food; }
primary class implementation
@interface FBDog : FBAnimal @end @interface FBDog () @end @implementation FBDog { @public FBFood *_food1; FBFood *_food2; FBFood *_food3; } @end void member_access() { FBFood *food = [[FBFood alloc] init]; FBAnimal *animal1 = [[FBAnimal alloc] init]; FBAnimal *animal2 = [[FBDog alloc] init]; FBDog *dog = [[FBDog alloc] init]; animal1->_food1 = 5; animal1->_food2 = 5; animal1->_food3 = 5; animal2->_food1 = 5; animal2->_food2 = 5; animal2->_food3 = 5; dog->_food1 = food; dog->_food2 = food; dog->_food3 = food; }
总结
数据成员编译期bind,根据instance object指针类型确定数据成员search起始class object从类体系结构分析,子类数据成员和父类数据成员可重名,但实际中primary class interface中数据成员不能与父类(直接或间接父类)数据成员重名,oc做此限制纯粹从类设计角度考虑,因为作为类提供者,一般只把primary class interface部分open给使用者,而隐藏extension和primary class implementation部分,子类继承父类(直接或间接父类),同理也一般只把primary class interface部分open给使用者,而隐藏extension和primary
class implementation部分,这样一来,如果oc不做上述限制,作为子类使用者,就无法使用父类(直接或间接父类)primary class interface中open给使用者的与子类primary class interface部分同名数据成员了,因为被子类屏蔽了
isa
NSObject包含Class isa数据成员,根据同一class object中,数据成员名不能重名,因此NSObject不允许再自定义isa数据成员Class isa定义在NSObject的primary class的interface中,因此继承自NSObject的子类(直接或间接子类)primary class interface中不能定义isa数据成员,extension和primary class implementation中则允许定义isa数据成员
相关文章推荐
- 使用结构中的成员变量在oc 中进行数据传递
- c++中类数据成员的重载问题
- 你知道数据大小吗?--不要花太多的功夫来隐藏类的成员(一)
- 面向对象设计原则1 把所有数据封装成类的私有成员
- C++中类的静态数据成员函数解析
- 1、永远使用属性替代可访问的数据成员
- 设计一个时间类Time, 包括时,分,秒等私有数据成员。要求实现时间的基本运算,一个时间加上另一个时间。。
- 类模板的友元函数的默认实参不能是 类模板的私有数据成员
- C++中访问类的私有数据成员的第三种方法
- C++静态数据成员和静态成员函数
- 你知道数据大小吗?--不要花太多的功夫来隐藏类的成员(二)
- Item 15.指向类数据成员的指针
- 关于private static数据成员
- [学习笔记]c#Primer中文版-类设计、static成员、const和readonly数据成员
- 使用属性,避免将数据成员直接暴露给外界
- 你知道数据大小吗?--不要花太多的功夫来隐藏类的成员(三)
- C++对象模型之数据成员模型(1)
- Item 15.指向类数据成员的指针
- 别忘记给c++类中的静态数据成员定义!
- 静态数据成员的初始值的指定