• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

AnintroductiontoObjective-CMetaClass

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
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.


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Objective-C工厂模式(下)--抽象工厂模式发布时间:2022-07-12
下一篇:
优雅的开发 Swift 和 Objective-C 混编的 Framework发布时间:2022-07-12
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap