6

BNRItemStore is a singleton, and I was confused on why super allocWithZone: must be called instead of plain old super alloc. And then override alloc instead of allocWithZone.

#import "BNRItemStore.h"

@implementation BNRItemStore

+(BNRItemStore *)sharedStore {
    static BNRItemStore *sharedStore = nil;

    if (!sharedStore)
        sharedStore = [[super allocWithZone: nil] init];

    return sharedStore;
}

+(id)allocWithZone:(NSZone *)zone {
    return [self sharedStore];
}

@end
stumped
  • 3,235
  • 7
  • 43
  • 76

2 Answers2

10

[super alloc] will call through to allocWithZone:, which you've overridden to do something else. In order to actually get the superclass's implementation of allocWithZone: (which is what you want there) rather than the overridden version, you must send allocWithZone: explicitly.

The super keyword represents the same object as self; it just tells the method dispatch mechanism to start looking for the corresponding method in the superclass rather than the current class.

Thus, [super alloc] would go up to the superclass, and get the implementation there, which looks something like:

+ (id) alloc
{
    return [self allocWithZone:NULL];
}

Here, self still represents your custom class, and thus, your overridden allocWithZone: is run, which will send your program into an infinite loop.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • stumped, this is on the subtler side of an introductory ObjC course, so if you've got questions about my answer, I'm happy to try to clarify. – jscs Aug 15 '12 at 01:29
  • Thanks! I do have one question. If I deleted the method that overrides allocWithZone: would it be safe to call super alloc instead of super allocWithZone: in sharedStore? – stumped Aug 15 '12 at 01:31
  • Yes. The reason for overriding `allocWithZone:` is to restrict any users of this class from creating another instance. They would call `alloc` (or possibly `allocWithZone:` directly; instead of allocating a new instance, you instead return the existing one. This is the key part of making the class a singleton. – jscs Aug 15 '12 at 01:35
  • Ohh I see. So is the decision between calling super alloc and overriding alloc vs. calling super allocWithZone: and overriding allocWithZone: completely arbitrary? – stumped Aug 15 '12 at 01:41
  • No, because if you overrode `alloc`, a client could still (conceivably) use `allocWithZone:` to create a new instance. Since `alloc` just calls through to `allocWithZone:`, overriding the latter covers both. – jscs Aug 15 '12 at 01:52
  • Thanks this conversation really helped! – stumped Aug 15 '12 at 02:57
  • 1
    @W'rkncacnter thanks for your explanation guy but I've a further question for you: why `[super alloc]` returns an instance of our custom class? Isn't `[super alloc]` calls the `alloc` method of parent class because of the word `super`? I can't figure out why `[super alloc]` returns the instance of our custom class **instead** an instance of `NSObject` - that is, the ***super*** class. (in OP's code the interface says `@interface BNRItemStore : NSObject`, I'm reading the same book :) – Fred Collins Aug 15 '12 at 23:04
  • @Fred: You should really post this as a separate question, because you'll get clearer and better answers than can fit in a comment, but `super` goes and looks in the superclass for the implementation of the method -- just the code. The identity of the object on which the method is called is the same as `self`. So the superclass's implementation of `alloc` does something like "get a chunk of zeroed memory the size of `self`'s class", not "get a chunk of memory the size of the class in which this method is implemented". If it did the latter, every subclass would have to provide its own `alloc`. – jscs Aug 16 '12 at 05:08
  • @W'rkncacnter Okay, then the `[super method]` means to execute the `method` found in the super class **on** the current class - that is, `self`, right? I get confused with your last sentence. Why every subclass would have to provide its own `alloc`? In this hypothetical case the research for the method `alloc` shouldn't go upwards until in the class hierarchy the method was found? – Fred Collins Aug 16 '12 at 08:42
  • @FredCollins: Please post a proper question rather than carrying this on in comments. – jscs Aug 16 '12 at 16:57
3

From Apple's documentation:

This method exists for historical reasons; memory zones are no longer used by Objective-C.

Rivera
  • 10,792
  • 3
  • 58
  • 102