I have implemented a singleton object using the regular pattern. My question is: is it possible to set this object back to nil, so that on a later called to [MySingleton sharedInstance] the object gets re-initialised?
// Get the shared instance and create it if necessary.
+ (MySingleton *)sharedInstance {
static dispatch_once_t pred;
static MySingleton *shared = nil;
dispatch_once(&pred, ^{
shared = [[MySingleton alloc] init];
});
return shared;
}
// We can still have a regular init method, that will get called the first time the Singleton is used.
- (id)init
{
self = [super init];
if (self) {
// Work your initialising magic here as you normally would
}
return self;
}
My guess is that
MySingleton *shared = [MySingleton sharedInstance];
shared = nil;
only sets the local pointer shared
to nil
. After all, shared
is declared as static
.
Your assumption about the local reference is correct, it won't affect your singleton.
To be able to reinitialize the singleton you need to move the static variable out of your method, so it's accessible by the whole class.
static MySingleton *sharedInstance = nil;
// Get the shared instance and create it if necessary.
+ (MySingleton *)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
}
+ (void)resetSharedInstance {
sharedInstance = nil;
}
Note that you cannot use dispatch_once
anymore, since your singleton needs obviously to be created multiple times. If you only ever call this singleton from your UI (and therefore only from the main thread), then the sample above is fine.
If you need access from multiple threads you need to put a lock around the +sharedInstance
and +resetSharedInstance
method, e.g.
+ (id)sharedInstance {
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
}
}
+ (void)resetSharedInstance {
@synchronized(self) {
sharedInstance = nil;
}
}
This is quite a bit slower than the dispatch_once
variant, but in practice it won't matter usually.
Yeah, but your singleton's sharedInstance
method defines it as a static
inside that method, and your final code sample is just setting a local variable (coincidentally also called shared
) to nil
, leaving the static
inside sharedInstance
unaltered. Thus you are just nil
-ing a local pointer, not changing the static
inside sharedInstance
.
If you want to do what you're asking, you'll have to pull the static
variable, shared
, out of the sharedInstance
method (and presumably write some reset
method to nil
it). Your sharedInstance
method also can no longer rely upon dispatch_once
, but rather have to check to see if that static
is nil
or not.
I did this. I'm not sure if it's the best way but it seemed to work fine.
static dispatch_once_t pred;
static MySingleton *shared = nil;
+(MySingleton *)sharedInstance {
dispatch_once(&pred, ^{
shared = [[MySingleton alloc] init];
});
return shared;
}
+(void)clearSharedInstance {
shared = nil;
pred = nil;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With