1

我又在读一本书,并且有这样的类实现:

@implementation BNRItemStore


// Init method
- (id)init
{
    self = [super init];

    if(self)
    {
        allItems = [[NSMutableArray alloc] init];
    }

    return self;

}

#pragma mark singleton stuff

// Implementing singleton functionality
+(BNRItemStore*) sharedStore
{
    static BNRItemStore *sharedStore = nil;

    // Check if instance of this class has already been created via sharedStore
    if(!sharedStore)
    {
        // No, create one
        sharedStore = [[super allocWithZone:nil] init];
    }

    return sharedStore;

}

// This method gets called by alloc
+ (id)allocWithZone:(NSZone *)zone
{
    return [self sharedStore];
}

#pragma mark Methods

// return pointer to allItems
-(NSArray*) allItems
{
    return allItems;
}

// Create a random item and add it to the array. Also return it.
-(BNRItem*) createItem
{
    BNRItem *p = [BNRItem randomItem];
    [allItems addObject:p];
    return p;
}

@end

我觉得奇怪的是,在类之外的任何地方,例如其他类,都是被调用的init方法。BNRItemStore然而,它仍然以某种方式被调用,即使有人在BNRItemStore类外键入了这样的代码:

    [[BNRItemStore sharedStore] createItem]; // This still calls the init method of BNRItemStore. How?

有人可以解释为什么吗?

4

2 回答 2

1
sharedStore = [[super allocWithZone:nil] init];

该线路负责init呼叫。sharedStore第一次输入sharedStore变量 is nil,所以条件检查失败并且类的一个实例被初始化。

于 2013-07-29T10:44:44.447 回答
0

-init被调用是因为+sharedStore调用它:

sharedStore = [[super allocWithZone:nil] init];

[super allocWithZone:nil]跳过当前类的 allocWithZone 实现并调用超类实现。但是,init 是一个普通的方法调用,因此它不会跳过超类的实现。

尽管引用的行使它看起来像 super 是您要向其发送消息的对象,但实际上它的意思是“自我,但跳过当前类的实现并改用超类”。它不会影响发送到返回对象的消息。

于 2013-07-29T10:45:07.717 回答