2012-06-21 4 views
0

У меня есть singleton и вы хотите создать внутреннюю флаговую переменную, которая должна указывать на то, что singleton был «выпущен», и когда я получаю экземпляр singleton, его следует повторно инициализировать.Статическая переменная в singleton

В этом случае я решаю использовать статическую переменную

static BOOL wasReleased = NO; 

и установить его на «YES» в истреблять функции:

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

Но когда я пытаюсь получить одноэлементный экземпляр этой переменной значение является всегда «НЕТ», поэтому внутренние ресурсы никогда не восстанавливаются после выпуска:

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

    if (wasReleased) 
    { 
     [sharedCoordinator initialize]; 
    } 

    return sharedCoordinator; 
} 

My unders возможно, неправильное обращение с такой ситуацией, пожалуйста, уточните это для меня.

+0

Вы имеете в виду, что это 'НЕТ' _after_ вы отправляете' destroy'? –

+0

Вы называете уничтожение вручную? потому что я предполагаю, что иначе объект просто не будет уничтожен. –

+0

Джош Касуэлл, да, его значение «НЕТ» после отправки 'destroy'. Я меняю значение «wasReleased» только в этих двух ситуациях, о которых идет речь выше. Я проверяю значение 'isReleased' внутри' destroy', поэтому это 'YES', как я ожидаю, но после этого нет. Joerg Simon, да, я вызываю «уничтожить» вручную, я использую точки останова, чтобы убедиться. – zakhej

ответ

0

Это не касается вашей непосредственной заботы, но вы должны пересмотреть свой дизайн. Уничтожение синглтона - это не очень хорошая идея. Если вы пытаетесь высвободить значительные ресурсы (изображения, видеоролики и т. Д.), Вы можете сделать фактические методы на синглете ответственным за их повторное создание.

Ниже не будет работать, как ожидалось:

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

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

Это совершенно правильным способом использовать синглтон, но в вашем случае, если вы не можете это сделать. Вместо того, чтобы ваш синглтон должен иметь такие методы, как в следующем:

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

    // do the rest 
} 
+1

Привет, Дэвид V, спасибо за ответ. Конечно, я не хочу выпускать экземпляр singleton, только ресурсы, инкапсулированные в singleton. Только одна проблема заключается в том, что я не могу понять, почему мой флаг bool не сохраняет его значение. Как я понимаю, ваш 'resourcesForMethodNotAllocated' имеет то же значение, что и мой' wasReleased'. – zakhej

+0

Я отредактировал сообщение, чтобы уточнить, что if (resourcesForMethodNotAllocated) был только концептуальным. Он может быть таким же, как isReleased boolean, хотя я бы предложил сделать его переменной экземпляра. Это может быть и другим, если разные методы нуждаются в разных ресурсах. Я не знаю, к чему относится ваша проблема. –

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; 
} 
+0

Можете ли вы объяснить, почему вы думаете, что это поможет? –

+0

Потому что объявление статической переменной экземпляра (для обоих случаев с 'isReleased' и' sharedCoordinator') и ее использование в методе класса не имеет смысла, потому что в методе класса вы не находитесь в области экземпляра. Метод класса не может получить доступ к переменным экземпляра, но вы можете получить к ним доступ из экземпляра ... – graver

+0

Это не переменная экземпляра - его нельзя было объявить как если бы это было - и нет такой вещи, как «статический экземпляр» переменная». Это «статическая» переменная уровня файла (доступная в методе класса); это обходной путь в ObjC для «переменных-членов класса». –

1

Мое понимание этой ситуации может быть неправильным, пожалуйста, прояснить свою позицию для меня.

Почему вы используете синглтон в первую очередь? Синглтон не должен быть освобожден или повторно инициализирован. Если вам нужно делать эти вещи, очень вероятно, что вам просто нужно создать новый экземпляр вашего класса, когда вам это нужно.

Кроме того, было бы неплохо избежать использования -initialize в качестве имени метода экземпляра, поскольку это можно легко смутить с помощью метода класса +initialize, который имеет каждый класс.

Смежные вопросы