在Objective-C中使用GCD的dispatch_once建立單例

若是您能夠定位iOS 4.0或更高版本 安全

使用GCD,這是在Objective-C(線程安全)中建立單例的最佳方法嗎? ide

+ (instancetype)sharedInstance
{
    static dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

#1樓

您能夠經過覆蓋alloc方法避免分配類。 spa

@implementation MyClass

static BOOL useinside = NO;
static id _sharedObject = nil;


+(id) alloc {
    if (!useinside) {
        @throw [NSException exceptionWithName:@"Singleton Vialotaion" reason:@"You are violating the singleton class usage. Please call +sharedInstance method" userInfo:nil];
    }
    else {
        return [super alloc];
    }
}

+(id)sharedInstance
{
    static dispatch_once_t p = 0;
    dispatch_once(&p, ^{
        useinside = YES;
        _sharedObject = [[MyClass alloc] init];
        useinside = NO;
    });   
    // returns the same object each time
    return _sharedObject;
}

#2樓

實例類型

instancetype只是Objective-C的許多語言擴展之一,每一個新發行版都添加了更多擴展。 線程

知道,愛它。 code

並以它爲例,說明如何關注底層細節能夠使您洞悉轉換Objective-C的強大新方法。 orm

參考此處:instancetype 對象


+ (instancetype)sharedInstance
{
    static dispatch_once_t once;
    static id sharedInstance;

    dispatch_once(&once, ^
    {
        sharedInstance = [self new];
    });    
    return sharedInstance;
}

+ (Class*)sharedInstance
{
    static dispatch_once_t once;
    static Class *sharedInstance;

    dispatch_once(&once, ^
    {
        sharedInstance = [self new];
    });    
    return sharedInstance;
}

#3樓

MySingleton.h get

@interface MySingleton : NSObject

+(instancetype)sharedInstance;

+(instancetype)alloc __attribute__((unavailable("alloc not available, call sharedInstance instead")));
-(instancetype)init __attribute__((unavailable("init not available, call sharedInstance instead")));
+(instancetype)new __attribute__((unavailable("new not available, call sharedInstance instead")));
-(instancetype)copy __attribute__((unavailable("copy not available, call sharedInstance instead")));

@end

MySingleton.m 博客

@implementation MySingleton

+(instancetype)sharedInstance {
    static dispatch_once_t pred;
    static id shared = nil;
    dispatch_once(&pred, ^{
        shared = [[super alloc] initUniqueInstance];
    });
    return shared;
}

-(instancetype)initUniqueInstance {
    return [super init];
}

@end

#4樓

若是要確保[[MyClass alloc] init]返回與sharedInstance相同的對象(我認爲這不是必需的,可是有些人想要),則能夠使用第二個dispatch_once輕鬆,安全地完成此操做: it

- (instancetype)init
{
    static dispatch_once_t once;
    static Class *sharedInstance;

    dispatch_once(&once, ^
    {
        // Your normal init code goes here. 
        sharedInstance = self;
    });

    return sharedInstance;
}

這容許[[MyClass alloc] init]和[MyClass sharedInstance]的任何組合返回相同的對象。 [MyClass sharedInstance]會更有效率。 工做原理:[MyClass sharedInstance]將調用一次[[MyClass alloc] init]。 其餘代碼也能夠屢次調用它。 初始化的第一個調用者將執行「常規」初始化,並將單例對象存儲在init方法中。 之後對init的任何調用都將徹底忽略返回的alloc並返回相同的sharedInstance; alloc的結果將被釋放。

+ sharedInstance方法將一如既往地工做。 若是不是第一個調用[[MyClass alloc] init]的調用者,則init的結果不是alloc調用的結果,可是能夠。


#5樓

要建立線程安全單例,您能夠執行如下操做:

@interface SomeManager : NSObject
+ (id)sharedManager;
@end

/* thread safe */
@implementation SomeManager

static id sharedManager = nil;

+ (void)initialize {
    if (self == [SomeManager class]) {
        sharedManager = [[self alloc] init];
    }
}

+ (id)sharedManager {
    return sharedManager;
}
@end

這個博客很好地解釋了objc / cocoa中的單例

相關文章
相關標籤/搜索