单例的几种创建方式

36 篇文章 0 订阅
6 篇文章 0 订阅

假设单例类名为XYXManager;

<在ARC下>

一、GCD

.h文件中

+(instancetype)shareInstance;

.m文件中

+ (XYXManager *)defaultManager { 
    static XYXManager *defaultInstance = nil;
    static dispatch_once_t predicate;  
    dispatch_once(&predicate, ^{  
        defaultInstance = [[self alloc] init];   
    });  
    return defaultInstance;  
}

优点:
1.这个方法可以在创建单例或者某些初始化动作时使用,以保证其唯一性。2.该方法是线程安全的,所以请放心大胆的在子线程中使用。(前提是你的dispatch_once_t *predicate对象必须是全局或者静态对象。这一点很重要,如果不能保证这一点,也就不能保证该方法只会被执行一次。)

二、@synchronized

.h文件中

+(instancetype)shareInstance;

.m文件中

+ (XYXManager *)defaultManager { 
    static XYXManager *defaultInstance = nil;
    @synchronized (self){
        if (!defaultInstance){
            defaultInstance = [[super allocWithZone:NULL]init];
        }
    }
    return bluetoothInstance; 
}

@synchronized,代表这个方法加锁, 相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程例如B正在用这个方法,有的话要等正在使用synchronized方法的线程B运行完这个方法后再运行此线程A,没有的话,直接运行。
优点:比GCD方法简明,同样是线程安全的,初始化alloc、init也都止执行一次。


需要注意的是,无论用方法一还是方法二,都应该实现以下父方法

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

-(id)copy{
return self;
}


很神奇的一个小技巧

如果不想在.m文件中写copy 和 allocWithZone方法,则可以在.h中设置禁止他人调用这两个方法:

+(instancetype)alloc NS_UNAVAILABLE;
+(instancetype)allocWithZone:(struct _NSZone *)zone NS_UNAVAILABLE;
-(id)copy NS_UNAVAILABLE;

另外一个很神奇的小技巧

如果数据需要初始化,可以放在_init中

.h中禁用
-(instancetype)init NS_UNAVAILABLE;
.m@interface XYXManager()
-(instancetype)_init;
@end

+(instancetype)shareInstance{
    static EPLBluetooth *bluetoothInstance = nil;
    @synchronized (self){
        if (bluetoothInstance == nil){
            bluetoothInstance = [[super allocWithZone:NULL]_init];
        }
    }
    return bluetoothInstance;
}

-(instancetype)_init{
    if (self = [super init]) {
        //do the init things
    }
    return self;
}

同样,若不想让外部调用init方法,也使用NS_UNAVAILABLE在h文件中设定

<在MRC下>

自觉添加上 release、retain、autorelease、retainCount方法

- (id) retain
{
    return [XYXManager shareInstance];
}
- (oneway void) release
{

}
- (instancetype) autorelease
{
    return self;
}
- (unsigned) retainCount
{
    return UINT_MAX;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值