Objective-C中的单身混淆

时间:2012-06-02 06:07:15

标签: objective-c

考虑以下代码:

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

如果我遵循这个单例设计模式,我可以做出以下假设:

  • 分配和初始化只会执行一次,谢谢 到GCD。
  • 只能从中访问sharedInstance类变量 在此实现中,无论实例如何,都在类之间共享。

我第一次创建实例时会做类似的事情:

MyClass *something = [MyClass sharedInstance];

我的问题是,如果我再次调用预览代码,但是这样:

MyClass *somethingOther = [MyClass sharedInstance];

我只能想到一个结果。

结果:

static MyClass *sharedInstance = nil;

使sharedInstance类变量指向nil并返回nil,因此somethingOther将为nil。

但是我认为在单例中应该发生的事情是将返回共享实例。

现在考虑以下代码:

+ (MotionManagerSingleton*)sharedInstance {

    static MotionManagerSingleton *_sharedInstance;
    if(!_sharedInstance) {
        static dispatch_once_t oncePredicate;
        dispatch_once(&oncePredicate, ^{
            _sharedInstance = [[super allocWithZone:nil] init];
            });
    }

    return _sharedInstance;
}

+ (id)allocWithZone:(NSZone *)zone {    

    return [self sharedInstance];
}

- (id)copyWithZone:(NSZone *)zone {
    return self;    
}

这里

static MotionManagerSingleton *_sharedInstance;

没有将我的变量设置为nil,但我认为默认情况下所有对象指针都被初始化为nil。

我的问题是,这些类方法如何返回“sharedInstance”?

由于

1 个答案:

答案 0 :(得分:3)

One。非初始化指针未初始化。

static MotionManagerSingleton *_sharedInstance;

不会使您的MotionManagerSingleton指向nil。它将指向一个未定义的(垃圾)位置。

两个。声明static的变量只初始化一次(是的,语法与语义有些不一致),所以你的第一个实现不会使返回的共享实例无效。这是一个非常好的实现。