Creating a singleton with allocWithZone:
Asked Answered
G

2

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
Glosseme answered 15/8, 2012 at 1:16 Comment(0)
M
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.

Madewell answered 15/8, 2012 at 1:20 Comment(10)
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.Madewell
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?Glosseme
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.Madewell
Ohh I see. So is the decision between calling super alloc and overriding alloc vs. calling super allocWithZone: and overriding allocWithZone: completely arbitrary?Glosseme
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.Madewell
Thanks this conversation really helped!Glosseme
@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 :)Holdup
@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.Madewell
@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?Holdup
@FredCollins: Please post a proper question rather than carrying this on in comments.Madewell
H
3

From Apple's documentation:

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

Horehound answered 11/10, 2013 at 7:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.