Objective-C中单例的正确开启方式

创建方式一: GCD创建

static id _instance = nil;

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

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

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

- (id)mutableCopyWithZone:(NSZone *)zone {
    
    return _instance;
}

创建方式二: 互斥锁创建

static id _instance = nil;
+ (instancetype)allocWithZone:(struct _NSZone *)zone {

    @synchronized(self) {
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
        }
    }
    return _instance;
}

+ (instancetype)sharedInstance {

    @synchronized(self) {        
        if (_instance == nil) {
            _instance = [[self alloc] init];
        }
    }    
    return _instance;
}
 - (id)copyWithZone:(NSZone *)zone {

    return _instance;
}
  • 单例创建之后我们还需要将原本的创建初始化方法屏蔽掉

方法一:在.h文件中声明禁止方法

+(instancetype) alloc __attribute__((unavailable("call other method instead")));
-(instancetype) init __attribute__((unavailable("call other method instead")));
+(instancetype) new __attribute__((unavailable("call other method instead")));

方法二:重载init、new

- (instancetype)init {

    [self doesNotRecognizeSelector:_cmd];
    return nil;
}
// -----或----- //
- (instancetype)init {
    return [self.class sharedInstance];
}
//------加------//
- (instancetype)new {
    return [self.class sharedInstance];
}

你可能感兴趣的:(Objective-C中单例的正确开启方式)