singleton with GCD

  • A calling object cannot instantiate a singleton object through other means of allocation. Otherwise, multiple instances of the singleton class could be created.
  • Restrictions on instantiating a singleton object should also coexist with the reference counting memory models.

 

Before GCD, we need to use synchronized to sync singleton instance,

but with GCD, we could use serial queue dispatch.

#import "RadioTuner.h"
 
static RadioTuner *sharedInstance = nil;
static dispatch_queue_t serialQueue;
 
@implementation RadioTuner
 
+ (id)allocWithZone:(NSZone *)zone {
    static dispatch_once_t onceQueue;    
 
    dispatch_once(&onceQueue, ^{
        serialQueue = dispatch_queue_create("com.duckrowing.radiotuner.SerialQueue", NULL);        
        if (sharedInstance == nil) {
            sharedInstance = [super allocWithZone:zone];
        }
    });
 
    return sharedInstance; 
}
 
+ (RadioTuner *)sharedTuner {
    static dispatch_once_t onceQueue;    
 
    dispatch_once(&onceQueue, ^{
        sharedInstance = [[RadioTuner alloc] init];
    });
 
    return sharedInstance;
}
 
- (id)init {
    id __block obj;
 
    dispatch_sync(serialQueue, ^{
        obj = [super init];
        if (obj) {
            currentStation = [[NSDecimalNumber alloc] initWithString:@"0.0"];           
        }
    });
 
    self = obj;
    return self;
}
 
- (void)setStation:(NSDecimalNumber *)station {
    dispatch_sync(serialQueue, ^{
        if (currentStation != station) {
            currentStation = station;
        }
    });
}
 
- (NSDecimalNumber *)currentStation {
    NSDecimalNumber __block *cs;
 
    dispatch_sync(serialQueue, ^{
        cs = currentStation;
    });
 
    return cs;
}
 
 
@end

 

Singleton template for xcode

//
//  ___FILENAME___
//  ___PROJECTNAME___
//
//  Created by ___FULLUSERNAME___ on ___DATE___.
//  Copyright ___YEAR___ ___ORGANIZATIONNAME___. All rights reserved.
//    File created using Singleton XCode Template by Mugunth Kumar (http://blog.mugunthkumar.com)
//  More information about this template on the post http://mk.sg/89    
//  Permission granted to do anything, commercial/non-commercial with this file apart from removing the line/URL above

#import "___FILEBASENAME___.h"

@implementation ___FILEBASENAMEASIDENTIFIER___

#pragma mark -
#pragma mark Singleton Methods

+ (___FILEBASENAMEASIDENTIFIER___*)sharedInstance {

    static ___FILEBASENAMEASIDENTIFIER___ *_sharedInstance;
    if(!_sharedInstance) {
        static dispatch_once_t oncePredicate;
        dispatch_once(&oncePredicate, ^{
            _sharedInstance = [[super allocWithZone:nil] init];
            });
        }

        return _sharedInstance;
}

+ (id)allocWithZone:(NSZone *)zone {    

    return [self sharedInstance];
}


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

#if (!__has_feature(objc_arc))

- (id)retain {    

    return self;    
}

- (unsigned)retainCount {
    return UINT_MAX;  //denotes an object that cannot be released
}

- (void)release {
    //do nothing
}

- (id)autorelease {

    return self;    
}
#endif

#pragma mark -
#pragma mark Custom Methods

// Add your custom methods here

@end

head file

//
//  ___FILENAME___
//  ___PROJECTNAME___
//
//  Created by ___FULLUSERNAME___ on ___DATE___.
//  Copyright ___YEAR___ ___ORGANIZATIONNAME___. All rights reserved.
//    File created using Singleton XCode Template by Mugunth Kumar (http://blog.mugunthkumar.com)
//  More information about this template on the post http://mk.sg/89
//  Permission granted to do anything, commercial/non-commercial with this file apart from removing the line/URL above

#import <Foundation/Foundation.h>

@interface ___FILEBASENAMEASIDENTIFIER___ : NSObject
+ (___FILEBASENAMEASIDENTIFIER___*) sharedInstance;
@end

 

for official version, please check cocoa foundation guide for singleton object creation

https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW55

static Singleton * sharedSingleton = nil; 
+ (Singleton*) sharedInstance 
{ 
if (sharedSingleton_ == nil) 
{ 
sharedSingleton_ = [[super allocWithZone:NULL] init]; 
} 
return sharedSingleton_; 
} 

+ (id) allocWithZone:(NSZone *)zone 
{ 
return [[self sharedInstance] retain]; 
}

But this
time, it calls [[super allocWithZone:NULL] init]to create a new instance instead of using other methods such as alloc. Why superbut not self? It’s because we have overridden the basic objectallocation methods in self, so we need to “borrow” the functionality from its parent, in this case NSObject, to help do the low-level memory allocation chores for us.

 

subclassing singleton

+ (Singleton *) sharedInstance 
{ 
if (sharedSingleton_ == nil) 
{ 
sharedSingleton_ = [NSAllocateObject([self class], 0, NULL) init]; 
} 
return sharedSingleton_; 
}

 

 

 

posted on 2012-06-19 14:18  grep  阅读(407)  评论(0编辑  收藏  举报