+ (void)initialize called only once?

To make a long story short: The answer is no!

Even if you don’t subclass, there are side effects you’d never thought possible.

A few days ago I ran into a tricky problem while working on my iTunes-Controller Playwatch. After spending some time debugging I came to the conclusion that only multiple calls to the “initialize-method” could cause the problem.

Apple’s documentation states, that initialize is called only once. If you create subclasses of your class, initialize gets called for each subclass. If the subclass does not implement it, the call is forwarded to the superclass. This is the exception to the rule. If you subclass, initialize of your superclass maybe called more than once. To avoid double initialization, the documentation recommends to check the class-instance and do initialization only if it’s the correct one.

Here’s the code:

@implementation MyClass
+ (void)initialize
{
	if(self == [MyClass class]) {
		// Do initialization here....
	}
}
@end

Since I did not have any subclasses, I thought I could run without this check. Far wrong! To find out what was going on, I set a breakpoint at initialize. The debugger stopped once, and a second time. Even with no subclasses. How could that be? A look at the Variable “self” shed some light on this miracle.

The first time the stack and the variable looked like this: (Click on the images to see full resolution)

The second time the result was as follows:

The first call to initialize is on the class “PWCoverArtAndTracks”. The second one is on the class “NSKVONotifying_PWCoverArtAndTracks”.

All right! The AppKit did create a subclass because I use the tracks-array of “PWCoverArtAndTracks” as the content binding for a NSCollectionView. As you can see at the picture below.

This is an implementation detail of CocoaBindings. I can remember reading something about this detail in the Apple Docs. But that remembrance was almost vanished at the time I wrote the initialize method.

Here’s my advice: Always check the class within initialize. Even if you don’t have subclasses.

Comments are closed.