Reputation: 273
I have found how to implement singleton in objective c (Non-ARC).
// AppTools.h in my code
@interface AppTools : NSObject {
NSString *className;
}
@property ( nonatomic, retain ) NSString *className;
+ ( id ) sharedInstance;
@end // AppTools
// AppTools.m in my code
static AppTools *sharedAppToolsInstance = nil;
@implementation AppTools
@synthesize className;
- ( id ) init {
self = [ super init ];
if ( self ) {
className = [ [ NSString alloc ] initWithString: @"AppTools" ];
}
return self;
} // init
- ( void ) dealloc {
// Should never be called, but just here for clarity really.
[ className release ];
[ super dealloc ];
} // dealloc
+ ( id ) sharedInstance {
@synchronized( self ) {
if ( sharedAppToolsInstance == nil )
sharedAppToolsInstance = [ [ super allocWithZone: NULL ] init ];
}
return sharedAppToolsInstance;
} // sharedInstance
+ ( id ) allocWithZone: ( NSZone * )zone {
return [ [ self sharedInstance ] retain ];
} // allocWithZone:
- ( id ) copyWithZone: ( NSZone * )zone {
return self;
} // copyWithZone:
- ( id ) retain {
return self;
} // retain
- ( unsigned int ) retainCount {
return UINT_MAX; // denotes an object that cannot be released
} // retainCount
- ( oneway void ) release {
// never release
} // release
- ( id ) autorelease {
return self;
} // autorelease
I'd like to know how to work allocWithZone: in sharedInstance method. On this, the allocWithZone: method's receiver is 'super' and 'super' is NSObject. Though return value is NSObject instance, it is substituted to sharedInstance.
Where is className's memory room then? I don't know how to work this part of the code.
Thank in advance.
Upvotes: 0
Views: 2461
Reputation: 144
I use the same code as Nekto but singleton = [[CustomClass alloc] init];
should be singleton = [[self alloc] init];
.
Imagine a subclass CustomSubclass
. If you call
CustomSubclass *sharedObject = [CustomSubclass shared];
you will not get a CustomSubclass
but a CustomClass
.
Upvotes: 2
Reputation: 53000
You ask "Where is className's memory room then?"
Most classes do not implement alloc
or allocWithZone
themselves but rely on the implementation inherited from NSObject
. The NSObject
implementation allocates an object of the original calling class.
So in your example AppTools
does override allocWithZone
, this implementation invokes NSObject
's allocWithZone
via a call to super
, and NSObject
's method performs the actual allocation and returns an object of type AppTools
.
[Note: If you are wondering how NSObject
's implementation knows what kind of object to allocate then this is simple - calling an inherited method does not alter the self
argument to the method, alloc
/allocWithZone
are class methods, and the self
argument of a class method references the class object (rather than an instance object of the class) itself.]
Upvotes: 1
Reputation: 17877
I think that code that you have posted is too difficult to use for creating singletons.
In all my project I am using the following code to use singletons. It is very simple, thread-safe and works perfectly:
+ (CustomClass *)shared
{
static CustomClass *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[CustomClass alloc] init];
});
return singleton;
}
And I believe you could use it in ARC and non-ARC projects.
UPDATE:
As mentioned in comments it is actually shared object
and not singleton
because there could be created more the one instance of particular class. But it is close enough.
In my opinion, if you are not writing open source code/libraries and nobody else will use it then it might be much easier to use shared objects and treat them as singletons.
Upvotes: 3