单例的实现方式

一、苹果官网推荐的单例方式

  • 此处重写+allocWithZone:方法,多线程是不安全的了,单例不止初始化一次
#import "MyGizmoClass.h"

static MyGizmoClass *sharedGizmoManager = nil;

@implementation MyGizmoClass

+ (MyGizmoClass *)sharedManager {
    if (sharedGizmoManager == nil) {
        NSLog(@"~~~~~~");
        sharedGizmoManager = [[super allocWithZone:NULL] init];
    }else {
        NSLog(@"^^^^^^^");
    }
    return sharedGizmoManager;
}

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


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

@end

在苹果官方的写法中,并不能保证多线程中的线程安全,我们用几个线程来调用sharedManager,会发现多次调用

- (void)test1 {
    dispatch_queue_t queue1 = dispatch_queue_create("com.yuna.testQueue1", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue2 = dispatch_queue_create("com.yuna.testQueue2", DISPATCH_QUEUE_SERIAL);
    __weak typeof(self) weakSelf = self;
    dispatch_async(queue1, ^{
        [weakSelf saleTicketNotSafe];
    });
    dispatch_async(queue2, ^{
        [weakSelf saleTicketNotSafe];
    });
}

- (void)saleTicketNotSafe {
    [MyGizmoClass sharedManager];
}

我们可以看到打印了两次~~~~~~
在这里插入图片描述

二、为了保证线程安全,可以使用@synchronized

#import "SynchronizedSingleClass.h"

@implementation SynchronizedSingleClass

+ (SynchronizedSingleClass *)sharedManager {
    static SynchronizedSingleClass *sharedSynchronizedSingleManager = nil;
    @synchronized (self) {//保证线程安全
        if (sharedSynchronizedSingleManager == nil) {
            sharedSynchronizedSingleManager = [[super allocWithZone:NULL] init];
            NSLog(@"~~~~~");
        }else {
            NSLog(@"^^^^^^");
        }
    }
    return sharedSynchronizedSingleManager;
}

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

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

@end
/*
 * 此处重写+allocWithZone:方法,再加上@synchronized 来保证线程安全
 */
- (void)test2 {
    dispatch_queue_t queue1 = dispatch_queue_create("com.yuna.testQueuq1", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue2 = dispatch_queue_create("com.yuna.testQueuq2", DISPATCH_QUEUE_SERIAL);
    
    __weak typeof(self) weakSelf = self;
    dispatch_async(queue1, ^{
        [weakSelf synchronizedTest];
    });
    dispatch_async(queue2, ^{
        [weakSelf synchronizedTest];
    });
}

- (void)synchronizedTest {
    /*
     * ~~~~~
     * ^^^^^^
     */
    [SynchronizedSingleClass sharedManager];
}

三、此处不用重写+allocWithZone:方法,而是直接用@synchronized 来保证线程安全

#import "SynchronizedDemoClass.h"

@implementation SynchronizedDemoClass
/*
 * //此处不用重写+allocWithZone:方法,而是直接用@synchronized 来保证线程安全
 */
+ (instancetype)sharedSingleton {
    static id instance = nil;
    @synchronized (self) {
        if (!instance) {
            instance = [[self alloc] init];
            NSLog(@"~~~~~~");
        }else {
            NSLog(@"^^^^^^^");
        }
    }
    return instance;
}
@end
/*
 * 此处不用重写+allocWithZone:方法,而是直接用@synchronized 来保证线程安全
 */
- (void)test3 {
    dispatch_queue_t queue1 = dispatch_queue_create("com.yuna.testQueuq1", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue2 = dispatch_queue_create("com.yuna.testQueuq2", DISPATCH_QUEUE_SERIAL);
    
    __weak typeof(self) weakSelf = self;
    dispatch_async(queue1, ^{
        [weakSelf synchronsizedDemoTest];
    });
    dispatch_async(queue2, ^{
        [weakSelf synchronsizedDemoTest];
    });
}

- (void)synchronsizedDemoTest {
    /*
     * ~~~~~
     * ^^^^^^
     */
    [SynchronizedDemoClass sharedSingleton];
}

四、dispatch_once来实现单例

#import "DispatchonceClass.h"

@implementation DispatchonceClass

+ (instancetype)sharedSingleton {
    static id instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
        NSLog(@"~~~~~~");
    });
    return instance;
}

@end
- (void)test4 {
    dispatch_queue_t queue1 = dispatch_queue_create("com.yuna.testQueuq1", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue2 = dispatch_queue_create("com.yuna.testQueuq2", DISPATCH_QUEUE_SERIAL);
    
    __weak typeof(self) weakSelf = self;
    dispatch_async(queue1, ^{
        [weakSelf dispatchOnceDemo];
    });
    dispatch_async(queue2, ^{
        [weakSelf dispatchOnceDemo];
    });
}

- (void)dispatchOnceDemo {
    [DispatchonceClass sharedSingleton];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值