OC怎么正确的写单例

今天偶然看到一篇文章,有所感触,这才发现写了好久的单例竟然并没有写正确,研究了一下,总结如下:

@interface MySingle() <NSCopying, NSMutableCopying>
@end

@implementation MySingle

+ (instancetype)sharedInstance {
    static MySingle *single = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"dispatch_once");
        single = [[super allocWithZone:NULL] init];
        
        // 下面代码进行当前类的初始化操作
        [single initSelf];
    });
    
    NSLog(@"shared called");
    
    return single;
}

// 初始化代码
- (void)initSelf {
    self.myName = @"OK";
}

// 不能使用下面这个类进行初始化,否则会陷入死循环,或会使用得外部调用[[xx alloc] init] 会再次触发这个方法
//- (instancetype)init {
//    NSLog(@"init called");
//    _myName = @"This is it.";
//    return self;
//}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    NSLog(@"allocWithZone");
    return [MySingle sharedInstance];
}

- (instancetype)copyWithZone:(NSZone *)zone {
    NSLog(@"copyWithZone");
    return self;
}

- (instancetype)mutableCopyWithZone:(NSZone *)zone {
    NSLog(@"mutableCopyWithZone");
    return self;
}

@end

使用时,下面几种方式都能访问到唯一的单例对象,且初始化方法也只会被调用一次,完美,收工。

    MySingle *allIN = [[MySingle alloc] init];
    NSLog(@"init:%@, name=%@", allIN, allIN.myName);
    
    MySingle *the = [MySingle sharedInstance];
    
    MySingle *copyIt = [the copy];
    NSLog(@"c:%@, name=%@", copyIt, copyIt.myName);
    
    NSLog(@"m:%@", [the mutableCopy]);

需要注意的是, 上面sharedInstance中写初始化时使用的是[super allocWithZone], 这里不能写成[self allocWithZone],否则会引发循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值