I just noticed a rather severe bug in my iPhone/iPad app: I have a class called AppDelegate that implements the UIApplicationDelegate protocol – like every iPhone app has. I’m using Core Data, and the AppDelegate sets up my managed object context (I mostly just left the default methods of the Xcode template in place).
Now I need the managed object context in a few places in my app and I would also like to call the -saveContext method from a few places. So I used the singleton pattern and added a class method + (AppDelegate *)sharedAppDelegate that is implemented like this:
+ (AppDelegate *)sharedAppDelegate
{
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred,^{
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}
Everything worked fine so far. Now however, I tried to access the sharedAppDelegate‘s UIWindow property and noticed it was nil. At first I was quite confused, but then I realized that first my main method creates an instance of AppDelegate, which creates the UIWindow and view controllers in -application:didFinishLaunchingWithOptions: and then, -sharedAppDelegate creates another one! I find it very strange that my app seemed to work quite well so far, because for instance only the first instance calls -saveContext when the app exists.
Anyway, I would like to change it so that the main method also uses the sharedAppDelegate. Does that mean that I need to override the -init method? How can I prevent an infinite loop (-sharedAppDelegate also calles init after all)? Should I make the _sharedObject variable of global scope?
You don’t create your own instance of the app delegate. The UIKit Framework creates one for you when the application starts up. You get the current app delegate from the
delegatemethod on UIApplication. So when you want to get your shared managed object context:You can always get the current singleton UIApplication objected with the
sharedApplicationmethod and you can always get the proper instance of your app delegate using thedelegatemethod on the application instance.