This question already has an answer here:
这个问题在这里已有答案:
- How do I implement an Objective-C singleton that is compatible with ARC? 10 answers
如何实现与ARC兼容的Objective-C单例? 10个答案
I saw thread safe version
我看到了线程安全的版本
+(MyClass *)singleton {
static dispatch_once_t pred;
static MyClass *shared = nil;
dispatch_once(&pred, ^{
shared = [[MyClass alloc] init];
});
return shared;
}
but what would happen if someone just calls [MyClass alloc] init]
? How to make it return same instance as the +(MyClass *)singleton
method?
但如果有人只是调用[MyClass alloc] init]会发生什么?如何让它返回与+(MyClass *)单例方法相同的实例?
3 个解决方案
#1
12
Apple recommends the strict singleton implementation (no other living object of the same type is allowed) this way:
Apple推荐使用严格的单例实现(不允许使用相同类型的其他生物对象):
+ (instancetype)singleton {
static id singletonInstance = nil;
if (!singletonInstance) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singletonInstance = [[super allocWithZone:NULL] init];
});
}
return singletonInstance;
}
+ (id)allocWithZone:(NSZone *)zone {
return [self singleton];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
Link to the apple documentation (bottom of page, Without ARC)
链接到Apple文档(页面底部,没有ARC)
#2
2
This might be helpful,
这可能会有所帮助,
static Foo *sharedInstance = nil;
+ (Foo *)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone {
@synchronized(self)
{
if (sharedInstance == nil) {
sharedInstance = [super allocWithZone:zone];
return sharedInstance;
}
}
return nil;
}
#3
0
I picked up this code sample from the duckrowing blog: http://www.duckrowing.com/2011/11/09/using-the-singleton-pattern-in-objective-c-part-2/
我从浏览博客中获取了此代码示例:http://www.duckrowing.com/2011/11/09/using-the-singleton-pattern-in-objective-c-part-2/
In the .h we have
在.h我们有
@interface Foo : NSObject
+ (Foo *) sharedFoo;
@end
and in the .m we have
在我们的.m
static SLFoo *sharedInstance = nil;
static dispatch_queue_t serialQueue;
@implementation Foo
- (id)init
{
id __block obj;
dispatch_sync(serialQueue, ^{
obj = [super init];
if (obj) {
;
}
});
self = obj;
return self;
}
+ (Foo *) sharedFoo;
{
static dispatch_once_t onceQueue;
dispatch_once(&onceQueue, ^{
if (sharedInstance) {
return;
}
sharedInstance = [[Foo alloc]init];
});
return sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone
{
static dispatch_once_t onceQueue;
dispatch_once(&onceQueue, ^{
serialQueue = dispatch_queue_create("com.mydomain.myApp.SerialQueueFoo", NULL);
if (sharedInstance == nil) {
sharedInstance = [super allocWithZone:zone];
}
});
return sharedInstance;
}
@end
Notice the allocWithZone.
请注意allocWithZone。
#1
12
Apple recommends the strict singleton implementation (no other living object of the same type is allowed) this way:
Apple推荐使用严格的单例实现(不允许使用相同类型的其他生物对象):
+ (instancetype)singleton {
static id singletonInstance = nil;
if (!singletonInstance) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singletonInstance = [[super allocWithZone:NULL] init];
});
}
return singletonInstance;
}
+ (id)allocWithZone:(NSZone *)zone {
return [self singleton];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
Link to the apple documentation (bottom of page, Without ARC)
链接到Apple文档(页面底部,没有ARC)
#2
2
This might be helpful,
这可能会有所帮助,
static Foo *sharedInstance = nil;
+ (Foo *)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone {
@synchronized(self)
{
if (sharedInstance == nil) {
sharedInstance = [super allocWithZone:zone];
return sharedInstance;
}
}
return nil;
}
#3
0
I picked up this code sample from the duckrowing blog: http://www.duckrowing.com/2011/11/09/using-the-singleton-pattern-in-objective-c-part-2/
我从浏览博客中获取了此代码示例:http://www.duckrowing.com/2011/11/09/using-the-singleton-pattern-in-objective-c-part-2/
In the .h we have
在.h我们有
@interface Foo : NSObject
+ (Foo *) sharedFoo;
@end
and in the .m we have
在我们的.m
static SLFoo *sharedInstance = nil;
static dispatch_queue_t serialQueue;
@implementation Foo
- (id)init
{
id __block obj;
dispatch_sync(serialQueue, ^{
obj = [super init];
if (obj) {
;
}
});
self = obj;
return self;
}
+ (Foo *) sharedFoo;
{
static dispatch_once_t onceQueue;
dispatch_once(&onceQueue, ^{
if (sharedInstance) {
return;
}
sharedInstance = [[Foo alloc]init];
});
return sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone
{
static dispatch_once_t onceQueue;
dispatch_once(&onceQueue, ^{
serialQueue = dispatch_queue_create("com.mydomain.myApp.SerialQueueFoo", NULL);
if (sharedInstance == nil) {
sharedInstance = [super allocWithZone:zone];
}
});
return sharedInstance;
}
@end
Notice the allocWithZone.
请注意allocWithZone。