如果你的目标系统是iOS 4.0或以上

使用GCD,它是在Objective-C(线程安全)中创建单例的最好方法吗?

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

当前回答

instancetype

instancetype只是Objective-C的众多语言扩展之一,每个新版本都会添加更多扩展。

了解它,热爱它。

并将其作为一个例子,说明如何关注底层细节可以让您深入了解转换Objective-C的强大新方法。

参考这里: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;
}

其他回答

@interface className : NSObject{
+(className*)SingleTonShare;
}

@implementation className

+(className*)SingleTonShare{

static className* sharedObj = nil;
static dispatch_once_t once = 0;
dispatch_once(&once, ^{

if (sharedObj == nil){
    sharedObj = [[className alloc] init];
}
  });
     return sharedObj;
}

可以避免通过覆盖alloc方法来分配类。

@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;
}

如果你想确保[[MyClass alloc] init]返回与sharedInstance相同的对象(在我看来没有必要,但有些人想要它),可以使用第二个dispatch_once非常容易和安全地完成:

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

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

    return sharedInstance;
}

This allows any combination of [[MyClass alloc] init] and [MyClass sharedInstance] to return the same object; [MyClass sharedInstance] would just be a bit more efficient. How it works: [MyClass sharedInstance] will call [[MyClass alloc] init] once. Other code could call it as well, any number of times. The first caller to init will do the "normal" initialisation and store the singleton object away in the init method. Any later calls to init will completely ignore what alloc returned and return the same sharedInstance; the result of alloc will be deallocated.

+sharedInstance方法将像往常一样工作。如果它不是第一个调用[[MyClass alloc] init]的调用者,那么init的结果不是alloc调用的结果,但这是可以的。

instancetype

instancetype只是Objective-C的众多语言扩展之一,每个新版本都会添加更多扩展。

了解它,热爱它。

并将其作为一个例子,说明如何关注底层细节可以让您深入了解转换Objective-C的强大新方法。

参考这里: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;
}

MySingleton.h

@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