- 此处重写+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];
}