在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
First, let's have a look at the base class NSObject. @interface NSObject <NSObject> { //implement protocol NSObject Class isa; //point to meta class, all instances of NSObject share the same meta class. } + (void)load; + (void)initialize; - (id)init; + (id)new; + (id)allocWithZone:(NSZone *)zone; + (id)alloc; - (void)dealloc; + (Class)superclass; + (Class)class; ... @end Class is defined as: typedef struct objc_class *Class; struct objc_class { Class isa; #if !__OBJC2__ Class super_class OBJC2_UNAVAILABLE; const char *name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; struct objc_method_list **methodLists OBJC2_UNAVAILABLE; struct objc_cache *cache OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; #endif } OBJC2_UNAVAILABLE; objc_class is the meta class. id is defined as: typedef struct objc_object { Class isa; } *id; id is an pointer pointed to struct obj_object very similar with the definition of NSObject. //class TestA @interface TestA : NSObject { int a; } + (id)alloc; + (void)initialize; @end @implementation TestA + (void)load { printf("load TestA. %s %#x\n", [[self description] UTF8String], self); } + (id)alloc { self = [super alloc]; printf("alloc TestA. %s %#x\n", [[self description] UTF8String], self); return self; } + (void)initialize { printf("initialize TestA. %s %#x\n", [[self description] UTF8String], self); } - (id)init { self = [super init]; if(self) { printf("init TestA. %s %#x isa=%#x\n", [[self description] UTF8String], self, isa); } return self; } @end //End of TestA //class TestB @interface TestB : TestA { int b; } + (id)alloc; + (void)initialize; @end @implementation TestB + (void)load { printf("load TestB. %s %#x\n", [[self description] UTF8String], self); } + (id)alloc { self = [super alloc]; printf("alloc TestB. %s %#x\n", [[self description] UTF8String], self); return self; } + (void)initialize { printf("initialize TestB. %s %#x\n", [[self description] UTF8String], self); } - (id)init { self = [super init]; if(self) { printf("init TestB. %s %#x isa=%#x\n", [[self description] UTF8String], self, isa); } return self; } @end //End of TestB //Testing example TestB *b1 = [[TestB alloc] init]; TestB *b2 = [[TestB alloc] init]; TestA *a1 = [[TestA alloc] init]; Output: initialize TestA. TestA 0xd634 load TestA. TestA 0xd634 initialize TestB. TestB 0xd65c load TestB. TestB 0xd65c alloc TestA. <TestB: 0x4e317f0> 0x4e317f0 alloc TestB. <TestB: 0x4e317f0> 0x4e317f0 init TestA. <TestB: 0x4e317f0> 0x4e317f0 isa=0xd65c init TestB. <TestB: 0x4e317f0> 0x4e317f0 isa=0xd65c alloc TestA. <TestB: 0x4e369e0> 0x4e369e0 alloc TestB. <TestB: 0x4e369e0> 0x4e369e0 init TestA. <TestB: 0x4e369e0> 0x4e369e0 isa=0xd65c init TestB. <TestB: 0x4e369e0> 0x4e369e0 isa=0xd65c alloc TestA. <TestA: 0x4e34930> 0x4e34930 init TestA. <TestA: 0x4e34930> 0x4e34930 isa=0xd634 From the outputs, some rules can be concluded: 1. In class method, such as initialize, load, alloc. self is the address of meta class, in another word, a pointer to struct objc_class. 2. The first time a class is referenced, its meta class will only be initialized and loaded once. 3. All instances of class objects share a meta class. 4. TestB inherits from TestA. The meta class address of TestB is 0xd65c. The meta class address of TestA is 0xd634. So TestB.isa->super_class = 0xd634. so TestB can call super's methods. All methods and meta infomations are stored in isa. |
请发表评论