Set aside any ideas you may have that global data is evil. If you spend any time on the StackOverflow website, you’ve likely seen questions like “How do I share data from one view controller with another view controller?” The answer is: use a global class. It turns out that every class is a global class, if you just include the right header file. But for the cases I am thinking about, a global class for accessing common data or common methods can work out really well.
The kind of global data, or application data, I am referring to are things like
- app state
- data or image caches
- utility methods used in multiple controllers
- and there are many more uses!
Convenience
One common need is to get a handle to your application delegate. Sure, you could do this every time you need it:#import "MyAppDelegate.h"
...
-(void)someMethod
{
MyAppDelegate *delegate = (MyAppDelegate *)
[[UIApplication sharedApplication] delegate];
...
}
Or, you could do this instead:
#import "AppData.h" // imports MyAppDelegate.h too
...
-(void)someMethod
{
MyAppDelegate *delegate = [AppData appDelegate];
...
}
Where you also have:
// AppData.h
#import "MyAppDelegate.h"
@interface AppData
+(MyAppDelegate *)appDelegate;
@end
// AppData.m
#import "AppData.h"
@implementation AppData
+(MyAppDelegate *)appDelegate
{
return (MyAppDelegate *)
[[UIApplication sharedApplication] delegate];
}
@end
You might ask: Why wouldn’t I just put these kinds of class methods in my app delegate? The answer is: You certainly can. But, as you saw, just getting the handle to your delegate is a non-trivial line of code.
The real advantage is in how your code-writing time can be shortened simply by being able to type something shorter to accomplish your task. Typing AppData is shorter than typing MyVeryLongAppNameAppDelegate. :-)
There are a myriad of class methods you could define in an AppData class both to simplify your code and make it easier to maintain. Consider custom colors that you need to use often. AppData class methods to the rescue. For example:
+(UIColor *)myAppColor
{
return [UIColor colorWithRed: ...];
}
Not only have you made it easier to get this color where you need it, you have also made it very easy to tweak it and have your change take effect everywhere it’s used (since the color definition is in just one place.)
Singletons
The utility of a global class also lends itself nicely to singleton objects.Consider some kind of data cache you need to maintain that you also need to access from multiple view controllers in your app. Easy! You might define your cache singleton class like this:
// Cache.h
@interface Cache : NSObject
{
NSMutableArray *data;
}
+(NSMutableArray *)data;
@end
// Cache.m
@implementation Cache
static Cache *_cache = nil;
+(void)initialize
{
_cache = [[Cache alloc] init];
_cache.data = [[NSMutableArray alloc] init];
}
+(NSMutableArray *)data
{
return _cache.data;
}
@end
Then to use this, you might do the following in your other code:
#import "Cache.h"
...
-(void)someMethod
{
...
[[Cache data] addObject:...];
...
}
To be sure, this example is a little contrived and the code as presented is certainly not complete nor devoid of some issues. But I think the idea is clear that with a global class you can achieve a number of benefits when it comes to code clarity, data sharing, and ease of maintenance.
Do you use global classes? What kinds of things do you use them for? If you don’t use them, why? Leave a comment!