Init function in singleton


#1

I think the Singleton example in the book could use a bit more explanation. While I know the Singleton Pattern from my experience in AS3, the implementation in the book has left me with a couple of questions.

One of those questions has already been answered on the forums, namely why you would ‘cripple’ allocWithZone instead of alloc.
If I understand correctly, by doing this you’re still allowing people to call our Singleton class by using

     PossessionStore *store = [[PossessionStore alloc] init];

you’re just changing it so that it will only give you a non-retained version of PossessionStore, the same way the class method + (PosessionStore *)defaultStore works. But why not just cripple the init function too and only allow it to throw an error or just do nothing? This would make it more obvious to other ‘classes’ or people using our class that they’re working with a Singleton.

Also, the NSMutableArray ‘allPossessions’ is initialized in the init function of our Singleton, not in our defaultStore class method. So if we would not be initialized if another class would just ask for our instance by sending the defaultStore message?

Or I just might be completely wrong in interpreting this and would love to be corrected. :slight_smile:
Either way, I think this is one of the subjects that could have been explained more thoroughly in the book.


#2

Okay, so basically after giving it more thought I understood that I had misinterpreted

by thinking that not only “super alloc” would be called, but also “super init”. So I know realize that our init method would still be called via the class method.

One question remains though, won’t another class be able to call our designated initializer?


#3

You’re correct that our init method would be called rather than the one in the superclass.

I’m not sure what you mean by “another class”. Yes, someone CAN try [[PossessionStore alloc] init]. NSObject’s +alloc invokes +allocWithZone:, which would use our overridden version, which would still return our singleton instance. That was really the point of overriding all those methods — to ensure that only our single instance would ever be returned, and it could not be released (because we overrode -release).

The one opportunity for it blowing up is if someone uses -autorelease; Apple overrides autorelease as well in their example. (See the last section of Cocoa Objects, called “Creating a Singleton Instance”.)

Incidentally, one quick clarification. In the original post, you mentioned that the changes return a “non-retained version of PossessionStore.” I assume you just meant “not explicitly retained by us” since even the singleton instance gets retained by super’s +allocWithZone:.


#4

Yes, I meant not retained by us. :slight_smile:

Well, I was confused about other classes being able to call our init function because in ActionScript this is not the case. AS3 is not able to have private constructors so we prevent other classes from calling it (and initializing our class in the process) by creating an internal class and making its instance a parameter of the init function. Since an internal class can only be called from the same document class, other objects can only get an instance by using the class method.