我使用常规模式实现了单例对象。我的问题是:是否可以将此对象设置为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
。
答案 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}},nil
内static
保持不变。因此,您只需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;
}