我在网上找到了一些信息,可以使用GCD创建单例类。那很酷,因为它是线程安全的,且开销很低。可悲的是,我找不到完整的解决方案,而只能找到sharedInstance方法的摘要。因此,我使用试错法(和其他方法)制作了自己的类,结果如下:

@implementation MySingleton

// MARK: -
// MARK: Singleton Pattern using GCD

+ (id)allocWithZone:(NSZone *)zone { return [[self sharedInstance] retain]; }
- (id)copyWithZone:(NSZone *)zone { return self; }
- (id)autorelease { return self; }
- (oneway void)release { /* Singletons can't be released */ }
- (void)dealloc { [super dealloc]; /* should never be called */ }
- (id)retain { return self; }
- (NSUInteger)retainCount { return NSUIntegerMax; /* That's soooo non-zero */ }

+ (MySingleton *)sharedInstance
{
    static MySingleton * instance = nil;

    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        // --- call to super avoids a deadlock with the above allocWithZone
        instance = [[super allocWithZone:nil] init];
    });

    return instance;
}

// MARK: -
// MARK: Initialization

- (id)init
{
    self = [super init];
    if (self)
    {
        // Initialization code here.
    }
    return self;
}

@end

请随时发表评论,并告诉我是否遗漏了某些东西或做的事情完全错误;)

干杯
斯特凡

最佳答案

把事情简单化:

+(instancetype)sharedInstance
{
    static dispatch_once_t pred;
    static id sharedInstance = nil;
    dispatch_once(&pred, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

- (void)dealloc
{
    // implement -dealloc & remove abort() when refactoring for
    // non-singleton use.
    abort();
}

这就对了。覆盖retainreleaseretainCount和其余的只是隐藏错误并添加许多行不必要的代码。每行代码都是一个等待发生的错误。实际上,如果您导致在共享实例上调用dealloc,则您的应用程序中存在一个非常严重的错误。该错误应修复,而不是隐藏。

这种方法还有助于重构以支持非单一使用模式。幸存的几个发行版中的每个单例最终都将重构为非单例形式。一些(例如NSFileManager)继续支持单例模式,同时还支持任意实例化。

请注意,以上内容在ARC中也“有效”。

关于ios - 正确的Singleton Pattern Objective C(iOS)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7598820/

10-10 03:14