0

我刚刚对公共库中使用的代码进行了分析,XCode 指出了以 [[[self alloc] 开头的行存在问题:

static MyClass *_sharedInstance = nil;

+ (MyClass*)sharedInstance
{
    if (_sharedInstance != nil) {
        return _sharedInstance;
    }

    @synchronized(self) {
        if (_sharedInstance == nil) {
            [[[self alloc] init] autorelease];
        }
    }

    return _sharedInstance;
}

当我看到这一行时,我不知道 _sharedInstance 怎么可能被分配。谁能向我解释为什么这段代码有效?我原以为你需要写:

_sharedInstance = [[[self alloc] init] autorelease];
4

2 回答 2

3

这是另一个过度思考+sharedInstance方法的例子,它充其量是令人困惑的,并且只能因为其他恶作剧(如覆盖release)而起作用。

只需这样做并完成它:

+ (id)sharedInstance
{
    static MyClass *sharedInstance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

简单,直接,并且不排除MyClass用作非单例。这样做的一个缺陷是如果+sharedInstance被递归调用,它会死锁,但+sharedInstance递归通常是一个不好的迹象。

于 2013-03-20T16:54:08.510 回答
0

它可能设置在 中alloc,而不是 init。这将防止在内部的递归调用中创建另一个实例init

解释:

复杂的单例进行大量设置是很常见的。这个设置可能很复杂,涉及的不仅仅是这个类。碰巧在此设置中从(深层)请求了单例。如果在调用之前_sharedInstance未设置变量,则会创建两个实例。init

于 2013-03-20T16:23:18.883 回答