oc——类——数据成员

来源:互联网 发布:游戏美工是什么专业 编辑:程序博客网 时间:2024/06/14 02:43

数据成员

类只有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@endvoid 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@endvoid 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;}@endvoid 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数据成员
0 0
原创粉丝点击