0

我有一个单例,想要创建一个内部标志变量,该变量应该指示单例已“释放”,并且当我获得单例实例时,它应该重新初始化自身。

对于这种情况,我决定使用静态变量

static BOOL wasReleased = NO; 

并在销毁函数中将其设置为“YES”:

- (void)destroy
{
    wasReleased = YES;
    ...release internal singleton resources...
}

但是当我尝试获取单例实例时,此变量值始终为“NO”,因此内部资源在释放后从未重新初始化:

+ (MySingleton *)sharedInstance
{
    if (sharedCoordinator == nil)
    {
        sharedCoordinator = [[super alloc] init];
        [sharedCoordinator initialize];
    }

    if (wasReleased) 
    {
        [sharedCoordinator initialize];
    }

    return sharedCoordinator;
}

我对这种情况的理解可能是错误的,请为我澄清一下。

4

3 回答 3

1

删除您的静态wasReleased实例变量并使其成为MySingleton类的属性(不要忘记合成它)

@property (nonatomic, assign) BOOL wasReleased;

然后在-destroy方法中:

- (void)destroy
{
    self.wasReleased = YES;
    //...release internal singleton resources...
}

然后(删除你的静态 ivar sharedCoordinator- 我想你有一个)

+ (MySingleton *)sharedInstance
{
    static MySingleton *sharedCoordinator = nil;
    if (!sharedCoordinator)
    {
        sharedCoordinator = [[MySingleton alloc] init];
        [sharedCoordinator initialize];
    }

    if (sharedCoordinator.wasReleased) 
    {
        [sharedCoordinator initialize];
        sharedCoordinator.wasReleased = NO; //If you are not doing it in the -initialize method
    }

    return sharedCoordinator;
}
于 2012-06-21T19:02:49.727 回答
1

我对这种情况的理解可能是错误的,请为我澄清一下。

你为什么首先使用单例?单例永远不需要被释放或重新初始化。如果您需要做这些事情,很可能您应该在需要时简单地创建类的新实例。

此外,最好避免将其用作实例方法名称,因为这很容易与每个类所具有-initialize的类方法混淆。+initialize

于 2012-06-22T14:33:31.187 回答
0

这并不能解决您的直接关注,但您应该重新考虑您的设计。销毁单例不是一个好主意。如果您试图释放大量资源(图像、视频等),您可以让单例上的实际方法负责重新实例化它们。

以下将无法按预期工作:

- (id)initSomeClassUsingTheSingleton
{
  mySingletonVariable = [MySingleton sharedInstance];
}

- (void)someOtherFunctionOccuringAfterDestroy
{
  [mySingletonVariable aMethodOnTheSingleton];
}

这是使用单例的一种完全有效的方法,但在您的情况下,您不能这样做。相反,您的单例应该具有如下方法:

- (void)aMethodOnTheSingleton
{
  //if resources for method not allocated
    // .. allocate

  // do the rest
}
于 2012-06-21T20:27:49.313 回答