I use:
#import <Foundation/Foundation.h>
@interface iCode_Framework : NSObject
@property (readonly, nonatomic) unsigned int iBufCapacity;
@property (readonly, nonatomic) unsigned int iPort;
@property (readonly, nonatomic) NSString * urlStr;
@end
#import "iCode_Framework.h"
static iCode_Framework * instance;
@implementation iCode_Framework
@dynamic iBufCapacity;
@dynamic iPort;
@dynamic urlStr;
- (unsigned int)iBufCapacity
{
return 1024u;
};
- (unsigned int)iPort
{
return 1978u;
};
- (NSString *)urlStr
{
return @"localhost";
};
+ (void)initialize
{
if (!instance) {
instance = [[super allocWithZone:NULL] init];
}
}
+ (id)allocWithZone:(NSZone * const)notUsed
{
return instance;
}
@end
Which is used exactly like a normal class, you call alloc and init! It is often convenient to assign to a variable to give a shorthand, because alloc and init are long to type, e.g.:
#import "iCode_FrameworkTests.h"
#import "iCode_Framework.h"
static iCode_Framework * c;
@implementation iCode_FrameworkTests
+ (void)initialize
{
c = [[iCode_Framework alloc] init];
}
- (void)setUp
{
[super setUp];
// Set-up code here.
}
- (void)tearDown
{
// Tear-down code here.
[super tearDown];
}
- (void)testSingletonNotNil
{
STAssertNotNil(c, nil);
}
- (void)testSingletonProperty
{
STAssertEqualObjects(c, [iCode_Framework alloc], nil);
}
- (void)testIBufCapacity
{
STAssertEquals(c.iBufCapacity, 1024u, nil);
}
@end
The advantage of this approach is it is used exactly like any other class and can therefore be mocked for testing.