如何正确实现ARC兼容和`alloc init`安全的Singleton类? [重复]

时间:2022-09-02 08:01:21

This question already has an answer here:

这个问题在这里已有答案:

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。