An introduction to Objective-C Meta Class

转自:http://www.cnblogs.com/qytan36/archive/2011/04/19/2021359.html


An introduction to Objective-C Meta Class

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.
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值