可以将单例设置为零吗?

Chu*_*584 15 null singleton ios

我使用常规模式实现了单例对象.我的问题是:是否可以将此对象设置为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;
}
Run Code Online (Sandbox Code Playgroud)

我的猜测是

MySingleton *shared = [MySingleton sharedInstance];
shared = nil;
Run Code Online (Sandbox Code Playgroud)

仅将本地指针设置sharednil.毕竟,shared被宣布为static.

Alf*_*nso 42

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

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

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

+ (void)resetSharedInstance {
    @synchronized(self) {
        sharedInstance = nil;
    }
}
Run Code Online (Sandbox Code Playgroud)

这比dispatch_once变体慢一点,但在实践中通常并不重要.


Rob*_*Rob 5

是的,但是你的单例sharedInstance方法将它定义为一个static内部方法,你的最终代码示例只是设置一个局部变量(巧合地也称为shared)nil,使static内部sharedInstance保持不变.因此,你只是nil一个本地指针,而不是改变static内部sharedInstance.

如果你想要做你的要求,你必须拉static变量shared,出的sharedInstance方法(可能写一些reset方法nil吧).你的sharedInstance方法也可以不再依赖dispatch_once,而是要检查,看看是否staticnil或不是.