单例创建的几种方法

方法一、(官方版)

这个方法为苹果公司官方的方法;

static id _sharedManager = nil;

+ (instancetype)defaultManager {
        if (_sharedManager == nil) {
            _sharedManager = [[super allocWithZone:NULL] init];
        }
    return _sharedManager;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    return [self sharedManager];
}

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

解释:

[[Class alloc] init];其实是做了两件事。 alloc 给对象分配内存空间,init是初始化对象,包括设置成员变量初值等。而给对象分配空间,除了alloc方法之外,还有另一个方法: + (instancetype)allocWithZone:
而使用alloc方法初始化一个类的实例的时候,默认调用了+ (instancetype)allocWithZone: 方法,所以创建单例覆盖这个方法也是必须的了。

方法二、(完整版)

//全局变量
static id _sharedManager = nil;

//单例方法
+(instancetype)shareManager{
    return [[self alloc] init];
}

//初始化方法
- (instancetype)init{
    // 只进行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedManager = [super init];
    });
    return _sharedManager;
}

//alloc会调用allocWithZone:
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    //只进行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedManager = [super allocWithZone:zone];
    });
    return _sharedManager;
}

//如果不刻意调用[object copy]�方法,下面的方法可以不使用
//copy会调用copyWithZone:
- (id)copyWithZone:(NSZone *)zone{
    return _sharedManager;
}

+ (id)copyWithZone:(struct _NSZone *)zone{
    return _sharedManager;
}

//mutableCopy会调用mutableCopyWithZone:
- (id)mutableCopyWithZone:(NSZone *)zone{
    return _sharedManager;
}

+ (id)mutableCopyWithZone:(struct _NSZone *)zone{
    return _sharedManager;
}

解释:

dispatch_once不仅意味着代码仅会被运行一次,而且还是线程安全的,这就意味着你不需要使用诸如@synchronized之类的来防止使用多个线程或者队列时不同步的问题。
对象是可以被copy/mutableCopy的,为了让被copy的对象也是“唯一”的,需要覆盖copy/mutableCopy的方法(如果可以保证不使用copy方法可以忽略这些方法的覆盖)

方法三、(简易版)

确保项目中只使用[Class shareManager]调用该类时可以用这个简易的方法。不能使用[[Class alloc] init];[object copy];这些方法调用呦~

+ (instancetype)shareManager {
    static ZingChatManager *_sharedManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedManager = [[Class alloc] init];
    });
    return _sharedManager;
}

你可能感兴趣的:(单例创建的几种方法)