Reputation: 77626
I know that the whole point of singleton is to instantiate 1 instance of the onject and reuse it, but when it comes to unit testing I want to be able to renew the singleton object before every test.
I tried to use a category to access the singleton object and release it but It's not accessible by categories any idea what's the best way to achieve this?
@implementation SingletonClass
static SingletonClass *singleton;
+ (SingletonClass*)sharedInstance
{
if (!singleton)
{
singleton = [[SingletonClass alloc] init];
}
return singleton;
}
@end
.
@implementation SingletonClass(Unit Testing Additions)
+ (void)killInstance
{
// I get an error here and I cannot access the singleton Object
[singleton release], singleton = nil;
}
@end
Upvotes: 0
Views: 1426
Reputation: 77626
Here is my own solution.
@implementation SingletonClass(Unit Testing Additions)
//Override
static SingletonClass *singleton;
+ (void)killInstance
{
// I get an error here and I cannot access the singleton Object
[singleton release], singleton = nil;
}
//Override
+ (SingletonClass*)sharedInstance
{
if (!singleton)
{
singleton = [[SingletonClass alloc] init];
}
return singleton;
}
@end
Upvotes: 0
Reputation: 162722
By the very definition of singleton, you can't do this.
If it is your class, don't make it a singleton.
If it isn't your class, doing this will fail.
Upvotes: 3
Reputation: 21464
If you want access to your singleton
global variable outside of the file in which it's declared, you'll need to make it globally accessible using extern
.
At the top of SingletonClass.h
, put this:
extern SingletonClass *singletonClassSingleton;
In your SingletonClass.m
, use this:
SingletonClass *singletonClassSingleton = nil;
Then assuming you have #import "SingletonClass.h"
in your unit test .m file, you should be able to add:
@implementation SingletonClass(Unit Testing Additions)
+ (void)killInstance
{
[singletonClassSingleton release], singletonClassSingleton = nil;
}
@end
The reason I've renamed singleton
to singletonClassSingleton
is that the variable is now global - if you have a bunch of singleton classes, you need these variables to have unique names, like dataManagerSingleton
, resourceManagerSingleton
or whatever.
Upvotes: 0
Reputation: 95355
I'm not sure whether this will work, but maybe you could just override the sharedInstance
class method and manage the singleton yourself:
@implementation SingletonClass (Unit Testing Additions)
static SingletonClass *myVeryOwnSharedInstance;
+ (SingletonClass *) sharedInstance
{
if (!myVeryOwnSharedInstance)
myVeryOwnSharedInstance = [[self alloc] init];
return myVeryOwnSharedInstance;
}
+ (void) killInstance
{
[myVeryOwnSharedInstance release];
// if release is overridden to do no-op, maybe just invoke -dealloc directly
myVeryOwnSharedInstance = nil;
}
@end
Upvotes: 1