可以将单例设置为零吗?

时间:2013-06-28 16:53:55

标签: ios singleton null

我使用常规模式实现了单例对象。我的问题是:是否可以将此对象设置为nil,以便在以后调用[MySingleton sharedInstance]时对象被重新初始化?

// Get the shared instance and create it if necessary.
+ (MySingleton *)sharedInstance {

    static dispatch_once_t pred;
    static MySingleton *shared = nil;
    dispatch_once(&pred, ^{
        shared = [[MySingleton alloc] init];
    });
    return shared;
}

// We can still have a regular init method, that will get called the first time the     Singleton is used.
- (id)init 
{
    self = [super init];

    if (self) {
    // Work your initialising magic here as you normally would

    }
    return self;
}

我猜是

MySingleton *shared = [MySingleton sharedInstance];
shared = nil;

仅将本地指针shared设置为nil。毕竟,shared被声明为static

3 个答案:

答案 0 :(得分:41)

您对本地参考的假设是正确的,它不会影响您的单身人士。

为了能够重新初始化单例,您需要将静态变量移出方法,因此整个类都可以访问它。

static MySingleton *sharedInstance = nil;
// Get the shared instance and create it if necessary.
+ (MySingleton *)sharedInstance {
    if (sharedInstance == nil) {
        sharedInstance = [[MySingleton alloc] init];
    }
    return sharedInstance;
}

+ (void)resetSharedInstance {
    sharedInstance = nil;
}

请注意,您不能再使用dispatch_once,因为您的单身人士显然需要多次创建。如果您只从UI中调用此单例(因此仅从主线程调用),那么上面的示例就可以了。

如果您需要从多个线程进行访问,则需要锁定+sharedInstance+resetSharedInstance方法,例如

+ (id)sharedInstance {
    @synchronized(self) {
        if (sharedInstance == nil) {
            sharedInstance = [[MySingleton alloc] init];
        }
        return sharedInstance;
    }
}

+ (void)resetSharedInstance {
    @synchronized(self) {
        sharedInstance = nil;
    }
}

这比dispatch_once变种要慢一些,但实际上通常并不重要。

答案 1 :(得分:5)

是的,但是您的单身人士的sharedInstance方法将其定义为该方法中的static,而您的最终代码示例只是将一个局部变量(巧合地称为shared)设置为{ {1}},nilstatic保持不变。因此,您只需sharedInstance - 一个本地指针,而不是更改nil内的static

如果您想要执行您要求的操作,则必须从sharedInstance方法中提取static变量shared(并且可能会写一些{{} 1}}方法到sharedInstance它)。您的reset方法也不再依赖nil,而是必须检查sharedInstance是否为dispatch_once

答案 2 :(得分:3)

我这样做了。我不确定这是不是最好的方式,但似乎工作正常。

static dispatch_once_t pred;
static MySingleton *shared = nil;

+(MySingleton *)sharedInstance {
        dispatch_once(&pred, ^{
            shared = [[MySingleton alloc] init];
        });
        return shared;
    }

+(void)clearSharedInstance {

       shared = nil;
       pred = nil;
}