Peter Hosey recently tweeted:
From the “how NOT to implement a Cocoa singleton” dept: http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32
If something over-releases an object, the bug is not in that object, and overriding methods in it to break retain/release is not fixing it.
The code sample in question is in the Apple documentation, and prescribes overriding the following methods for a singleton object:
retainCount. In addition, it also recommends implementing a
sharedFloozit class method, so that users of your class are aware they’re using a singleton. Go read that section, or you’ll be lost for the rest of this post.
Really, I mean it. Go read that documentation. I’ll be referring to it a lot.
That’s a lot of methods to override just to implement a singleton. More to the point, a lot of it seems unnecessary. After all, as long as everyone else is doing their memory management correctly, retain counts shouldn’t matter, right?
First, though, we need to get a definition straight. A singleton is a class of which there should only be one instance in any given process. There are actually very few singleton classes in the Cocoa framework including
NSFontManager.  You cannot create more than one of these objects; if you try to call
[[NSDocumentController alloc] init], you’ll get back the exact same object as you do when you call
[NSDocument sharedDocumentController], no matter how many times you call alloc and init.
NSApplication is arguably a singleton as well; you can alloc another one, but you’ll get an assertion failure when you call init.
Singletons are generally useful when initializing an object takes an inordinate amount of time.
NSFontManager, for example, has to search several locations on the filesystem in order to do its job. You really don’t want to be constantly initializing an
NSFontManager. Further, it makes very little sense to have more than one instance of
NSApplication within your application. Having one shared object for the whole system can simplify and optimize certain things. 
So that’s a singleton. Only one instance allowed in the entire process.
There are other classes that have a
+[SomethingClass sharedSomething] method or a
+[SomethingClass defaultSomething] method. These methods provide access to an instance of the object intended to be shared by all users of the class, but do not prohibit the creation of another instance. Indeed, the Leopard Developer Release Notes specifically note that creating multiple instances of
NSFileManager is possible and thread-safe, despite the existence of a globally-available object through
+[NSFileManager defaultManager]. These are not singletons. If you’re writing a class which provides a shared instance but doesn’t not prohibit creation of other instances, then you should absolutely not override
retainCount, and should probably not override
Most of the time, you don’t need a singleton. Just the mention of a singleton is enough to get some people up in arms. But if you really truly need a singleton, then there’s good reason for overriding the methods listed above.
Consider the following example:
MyFloozit *floozit1 = [[MyFloozit alloc] init];
MyFloozit *floozit2 = [[MyFloozit alloc] init]; // MyFloozit is a singleton, so this should be the same object as floozit1
[floozit2 doSomething]; // CRASH HERE
floozit1 is set, a new
MyFloozit is allocated, and a static
MyFloozit pointer is set. When
floozit1 is released, that static pointer is still pointing to the old instance. As a result, when we try to set
floozit2 (or when anyone else tries to call
[MyFloozit sharedFloozit]), we get back a pointer to that same instance. The one that has been dealloc-ed. Right there, despite following all the standard rules of memory management, you’ve crashed. The example might seem contrived, but if
floozit2 are in separate methods (or separate threads calling the same method), this could be a very common scenario.
The point is, if you override
allocWithZone: to force a class to be a singleton, then you must override
autorelease), or else anyone who believes they have ownership (after to calling
init) will crash your program. Once you’re disabling retain counting by overriding
release, you might as well override
retainCount as well, to be consistent.
In the Apple Documentation linked above, there is a short paragraph right after the code showing the recommended way to override the various methods. It says:
Situations could arise where you want a singleton instance (created and controlled by the class factory method) but also have the ability to create other instances as needed through allocation and initialization. In these cases, you would not override
allocWithZone:and the other methods following it as shown in Listing 2-15.
In this situation, I agree with Peter (and Apple) completely; don’t override the memory management methods. I disagree with calling it a singleton, but whatever you want to call it, it’s clear that you need those memory management methods.
If you think you need a singleton, think again. If you still think you need a singleton, bounce it off someone else to disabuse you of the notion. If you still need a singleton, then follow Apple’s advice and override the memory management methods. Otherwise, you’ll crash.
Of course, if you’re using garbage collection, all retain count operations are no-ops, so none of this matters anyway. Feel free to go on your merry way, pitying the poor souls still living in a retain-counted world.
 The documentation referenced by Peter on “Creating a Singleton Instance” lists
NSWorkspace as examples of singletons, but this is incorrect. It is possible to create more than one instance of both these classes; Cocoa just happens to provide easy access to a shared instance which they suggest you use.
 It can also complicate a lot of things by introducing shared state. I’m not arguing for the use of the singleton pattern; I agree with Peter that most of the time, if you’re using a singleton then you’re “Doin It Rong”. I’m simply arguing for Apple’s implementation of the singleton pattern in the case where you really do need a singleton.