by ampatspell
in Code
Objective-C has no class variables but they can be easily faked using C static global variable (and optionally +initialize) like this:
#import "Zeeba.h" static NSString *gZeebaSomething; @implementation Zeeba + (void)initialize { gZeebaSomething = @"is here"; } + (NSString *)something { return gZeebaSomething; } @end
The other approach would be creating another class (ZeebaSettings here), implement it as a singleton (using macro) and let it encapsulate global variable with all required logic:
// ZeebaSettings.h #import <Cocoa/Cocoa.h> @interface ZeebaSettings : NSObject { NSString *value; } @property(nonatomic, readonly, retain)NSString *value; + (ZeebaSettings *)sharedSettings; - (id)init; @end // ZeebaSettings.m #import "ZeebaSettings.h" #import "AMSingleton.h" @interface ZeebaSettings () @property(nonatomic, readwrite, retain) NSString *value; @end @implementation ZeebaSettings @synthesize value; AM_SINGLETON_BOILERPLATE(ZeebaSettings, sharedSettings) - (id)init { if(self = [super init]) { value = @"Hello world"; } return self; } - (void)dealloc { self.value = nil; [super dealloc]; } @end
And now Zeeba can use ZeebaSettings singleton instance:
#import "Zeeba.h" #import "ZeebaSettings.h" @implementation Zeeba + (NSString *)something { return [[ZeebaSettings sharedSettings] value]; } @end
Still, one thing is missing — AMSingleton.h. It’s just a macro what adds boilerplate code for singleton pattern to work while following Apple recomendations:
#define AM_SINGLETON_BOILERPLATE(_className_, _accessorName_) \ static _className_ *shared##_className_ = nil; \ + (_className_ *)_accessorName_ \ { \ @synchronized(self) { \ if(shared##_className_ == nil) { \ [[self alloc] init]; \ } \ } \ return shared##_className_; \ } \ \ + (id)allocWithZone:(NSZone *)zone \ { \ @synchronized(self) { \ if(shared##_className_ == nil) { \ shared##_className_ = [super allocWithZone:zone]; \ return shared##_className_; \ } \ } \ NSLog(@"Use +[%s %s] to access singleton instance", #_className_, #_accessorName_); \ return nil; \ } \ \ - (id)copyWithZone:(NSZone *)zone \ { \ return self; \ } \ \ - (id)retain \ { \ return self; \ } \ \ - (NSUInteger)retainCount \ { \ return NSUIntegerMax; \ } \ \ - (void)release \ { \ } \ \ - (id)autorelease \ { \ return self; \ }
This is reblog from my older blog @ tumblr.