单例Singleton

先提供一个完整版:

// .h文件
@interface SingleTon : NSObject
/** 
 获取单例对象
 */
+ (instancetype)sharedInstance;
+ (instancetype)new __attribute__((unavailable("new unavailable, call sharedInstance instead")));
- (instancetype)init __attribute__((unavailable("init unavailable, call sharedInstance instead")));
+ (instancetype)alloc __attribute__((unavailable("alloc unavailable, call sharedInstance instead")));
@end


// .m文件
static SingleTon *_instance;
@implementation SingleTon
+ (instancetype)sharedInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super alloc] initInstance];
    });
    return _instance;
}

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

+ (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;
}
@end

 

建议构造单例对象时,禁止调用系统的alloc、init等方法。以防止新加入的程序员在调用时出现问题;

下面来如何说说‘禁用’init等方法:

1、Clang特性(推荐,xcode不会联想该方法)

- (instancetype)init __attribute__((unavailable("init unavailable, call sharedInstance instead")));

 

2、使用apple提供的宏

- (instancetype)init NS_UNAVAILABLE;

 

3、在.m的 init中实现:

- (instancetype)init {
    [super doesNotRecognizeSelector:_cmd];
    return nil;
}

若init方法被调用了,则抛出异常信息:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TestManager init]: unrecognized selector sent to instance 0x600000001150'

 

4、断言或使用NSException,在init被调用时,则抛出异常信息

// NSAssert断言
- (instancetype)init {
    NSAssert(false,@"init unavailable, use sharedInstance instead");
    return nil;
}

// NSException
- (instancetype)init {
    [NSException raise:NSGenericException
                format:@"init unavailable. use +[%@ %@] instead",
     NSStringFromClass([self class]),
     NSStringFromSelector(@selector(sharedInstance))];
    return nil;
}

 

参考:http://stackoverflow.com/questions/5720029/create-singleton-using-gcds-dispatch-once-in-objective-c

posted @ 2016-09-28 16:13  Kingdev  阅读(390)  评论(0编辑  收藏  举报