iPhone proper usage of Application Delegate
IphoneObjective CCocoa TouchIphone Problem Overview
I'm looking to be able to reference certain state/objects through anywhere in my application. For instance, a user logs in to their application, I need to call a web service and retrieve the users information. Then I want to be able to access this information from anywhere in the application with something like the following:
myAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
user = delegate.u;
Is setting an instance variable as a User object in the app delegate and referencing it from there when needed a poor way of going about it? I typically set it there upon the user's login.
Wanted to hear how the pros handle this one.
Iphone Solutions
Solution 1 - Iphone
Normally, you should only connect things to the app delegate if they:
- Were created from the same NIB file as the app delegate (i.e. static UI elements in single window interfaces)
- Are associated with application-level event handling that passes through the app delegate (like the menu item for the Preferences Window)
For everything else, you should create a singleton which manages access to them.
Jason Coco suggested routing through the Application Controller. In my programs I normally avoid this, as I think it puts too much responsibility at the top level -- I think things should self-manage where possible and that higher level management should only be used when there is a requirement for coordination between peer-level modules.
I'm not going link my own blog but if you Google me and singletons you'll probably find a post I wrote going into more detail.
Solution 2 - Iphone
Matt is a bit too modest. His posting on the subject is one of the best I have read, and deserves a link. http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html
Solution 3 - Iphone
I don't see any problem with your approach. I usually use a singleton to handle this situation:
// MyCommon.h:
@interface MyCommon
class MyCommon : NSObject
{
int user;
};
@property(assign) int user;
(MyCommon *)singleton;
@end
// MyCommon.m:
@implementation MyCommon
static MyCommon * MyCommon_Singleton = nil;
(MyCommon *)singleton
{
if (nil == MyCommon_Singleton)
{
MyCommon_Singleton = [[MyCommon_Singleton alloc] init];
}
return MyCommon_Singleton;
}
@end
(MyCommon *)singleton { if (nil == MyCommon_Singleton) { MyCommon_Singleton = [[MyCommon_Singleton alloc] init]; }
return MyCommon_Singleton; } @end
The MyCommon
singleton is then used anywhere in my application as follows:
int user = [MyCommon singleton].user;
Solution 4 - Iphone
Usually you would ask your application's controller for this information and it would be responsible for knowing how to store it/look it up in whatever data model exists. Your application's controller may or may not be the same as the applications delegate (in most simple applications, it is the same).