1
votes

i am working on a project in wich i want to use Singleton Pattern model. i want to any data model of my this project fallow Singleton Pattern. i study the apple documentation regarding this

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW6

and

http://www.oodesign.com/singleton-pattern.html

http://www.daveoncode.com/2011/12/19/fundamental-ios-design-patterns-sharedinstance-singleton-objective-c/

now i know my custom object classes should fallow the main rule of allocing a object but the i need the complete implementation like using of this class object i am new in iphone app development so if i am wrong in any place in this Question please guide

6
The answer to the question "What does your Objective-C singleton look like?" might help you.Wolfram

6 Answers

1
votes
static MyClass *_sharedInstance;

+ (MyClass *)sharedMyClass
{
    @synchronized([MyClass class]) {
        if (_sharedInstance == nil)
            [[self alloc] init];

        return _sharedInstance;
    }

    return nil;
}

+(id) alloc
{
    @synchronized([MyClass class]) {
        NSAssert(_sharedInstance == nil, @"Attempted to allocate a second instance of MyClass.");
        _sharedInstance = [super alloc];
        return _sharedInstance;
    }

    return nil;
}

+ (id) allocWithZone:(NSZone *)zone 
{
    @synchronized([MyClass class]) {
        NSAssert(_sharedInstance == nil, @"Attempted to allocate a second instance of MyClass.");
        _sharedInstance= [super allocWithZone:zone];
        return _sharedInstance;
    }
    return nil; //on subsequent allocation attempts return nil
}

- (id) copyWithZone:(NSZone *)zone 
{
    return self;
}

- (id)retain
{
    return self;
}

- (NSUInteger)retainCount
{
    return NSUIntegerMax;
}

- (oneway void)release
{
    // Do nothing
}

- (id)autorelease
{
    return self;
}
2
votes

Try this:

@implementation Singleton

+ (Singleton *)sharedInstance
{
     static Singleton *obj = nil;

    if (obj == nil)
        obj = [[self alloc] init];

    return obj;
}

@end
1
votes

If you can target iOS 4 or above, I will take the following way:

//.h
+(MySingletonClass *)mySharedInstance;
-(void)doSomething;

//.m
+(MySingletonClass *)mySharedInstance {
    static dispatch_once_t pred;
    static MySingletonClass *shared = nil;

    dispatch_once(&pred, ^{
      shared = [[MySingletonClass alloc] init];
    });
    return shared;
}

-(void)doSomething
{
}

// override also the init if you want

To access it, do an #import MySingletonClass.h and use it wherever you want like the following:

MySingletonClass* mySharedInstance = [MySingletonClass mySharedInstance];
[mySharedInstance doSomething];

I want to any data model of my this project fallow Singleton Pattern.

Based on my experience, I would not abuse on singletons. The application could become difficult to maintain. To avoid this, put the data models within your singleton. You can access data model directly (creating properties around them) or using public methods (like for example doSomething) as wrappers.

Hope this helps.

0
votes

Typically I create the object in the

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

method and have it live in that object. I make it available to the rest of the app with a macro:

#define APPLICATION ((AppDelegate*)([UIApplication sharedApplication].delegate))

as a readonly property of the app delegate

The benefit of this type of approach if you are in to mocking is that it is just another object property rather than a hidden static object.

0
votes

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.