swift / Objective-C - 单例

- 在iOS OC中,用官方推荐的写法来写单例:

+ (instancetype)sharedInstance {
    static DBManager * ins = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        ins = [[DBManager alloc] init];
    });
    return ins;
}

DBManager *a = [DBManager sharedInstance];
接下来,可以用 a 这个单例来干很多事情了,看起来没有问题。在很多实际的项目中,很多人也的确是这么做的。

但是,这种方式若用 alloc,new 等来创建对象,此时新建的对象就不是原来的单一对象了,而是新的

	// a,b,c 3个对象的地址是不同的:
    DBManager* a = [DBManager sharedInstance];
    DBManager* b = [[DBManager alloc] init];
    DBManager* c = [DBManager new];

我们可以知道,Apple有很多的单例对象也是这样的,比如 NSFileManager
根据需要,我们可以采用这种方式,这种方式或许不叫单例,而只是提供一个公用对象,也可以像下面,写一个真正的单例


创建一个真正的单例,就是不管我用何种方法创建对象,都必须是同一个:

+ (instancetype)sharedInstance {
    static DBManager * ins = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        ins = [[super allocWithZone:nil] init];
    });
    return ins;
}

+(id)allocWithZone:(NSZone *)zone{
    return [self sharedInstance];
}
-(id)copyWithZone:(NSZone *)zone{
    return [[self class] sharedInstance];
}
-(id)mutableCopyWithZone:(NSZone *)zone{
    return [[self class] sharedInstance];
}

这些就都是同一个对象了:

	DBManager *a = [DBManager sharedInstance];
    DBManager *b = [[DBManager alloc]init];
    DBManager *c = [DBManager new];
    DBManager *d = [a copy];

ps: 也可以禁用掉别的对象生成方式:

+(instancetype) alloc __attribute__((unavailable("replace with 'sharedInstance'")));

+(instancetype) new __attribute__((unavailable("replace with 'sharedInstance'")));

-(instancetype) copy __attribute__((unavailable("replace with 'sharedInstance'")));

-(instancetype) mutableCopy __attribute__((unavailable("replace with 'sharedInstance'")));

swift 单例写法

let是线程安全的

方法一

如果没有特别的需求,我建议都使用这样的方式实现单例。

class Manager {
    static let sharedInstance = Manager()
}

方法二

private let sharedInstance = Manager()

class Manager {
    class var sharedManager: Manager {
        return sharedInstance
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值