Подтвердить что ты не робот

Статический класс против Синглтона

Итак, довольно простой вопрос. Игнорирование последствий чрезмерного использования одноэлементного шаблона. Я пытаюсь найти надежный однотонный patter в Objective-C. Я столкнулся с этим:

@implementation SomeSingleTonClass

static SomeSingleTonClass* singleInstance;

+ (SomeSingleTonClass*)getInstance
{
    static dispatch_once_t dispatchOnceToken;

    dispatch_once(&dispatchOnceToken, ^{
        singleInstance = [[SomeSingleTonClass alloc] init];
    });

    return singleInstance;
}

- (void)someMethodOnTheInstance
{
    NSLog(@"DO SOMET WORK")
}

@end

Это я доволен, но это приводит к большому количеству этого:

[[SomeSingleTonClass getInstance] someMethodOnTheInstance];

Мой вопрос: почему это лучше, чем чисто статический класс.

@implementation SomeStaticClass

static NSString* someStaticStateVariable;

- (id)init
{
    //Don't allow init to initialize any memory state
    //Perhaps throw an exception to let some other programmer know
    //not to do this
    return nil;
}

+ (void)someStaticMethod
{
    NSLog(@"Do Some Work");
}

Все, что вы действительно на самом деле получаете, - это мягко очищающие вызовы методов. В основном вы меняете это:

[[SomeSingleTonClass getInstance] someMethodOnTheInstance];

Для этого

[SomeStaticClass someStaticMethod];

Это небольшое упрощение, и вы всегда можете сохранить экземпляр внутри своего класса. Это более интеллектуальное любопытство, что Objective-C бог, я писаю, используя статические классы вместо синглтонов? Я уверен, что я не могу быть первым, кто думает об этом, но я обещаю, что сначала сделал двойной поиск. Несколько ответов, которые я нашел, я чувствовал, что они были основаны на более старых версиях cocoa, потому что даже обсуждаемые шаблоны одноэлементных, казалось, страдали от проблем с потоками.

4b9b3361

Ответ 1

Ты злишься без богов Objective-C с таким классом. Фактически, Apple рекомендует использовать этот шаблон в некоторых случаях (я думаю, они упомянули об этом в одном из видеороликов ARC, где обсуждались общие шаблоны проектирования и способы их реализации с использованием ARC).

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

Ответ 2

Статический класс. Используется, когда вы хотите группировать методы полезности, независимые от состояния.

Синглтон: используется, когда у вас есть несколько методов, которые разделяют состояние.

Ответ 3

Я нашел удобным сделать сочетание обоих. Я использую стандартный одноэлементный шаблон, похожий на ваш первый, который приводит к:

[[MyClass defaultInstance] doSomething];

Но я также хочу иметь возможность создавать другие экземпляры одного и того же класса:

MyClass *secondInstance = [[MyClass alloc] init];
[secondInstance doSomething];

Когда я хочу более сжатый доступ к методам вызова для экземпляра singleton, я определяю методы класса следующим образом:

// class method to call a method on the singleton instance
+ (void)doSomething
{
    [[MyClass defaultInstance] doSomething];
}

Таким образом, я могу использовать:

[MyClass doSomething];

Ответ 4

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

В следующем примере показан класс, который никогда не будет создан. Опять же, основная цель класса в Objective-C состоит в том, чтобы действовать как factory для экземпляров, поэтому класс, который никогда не создавался, не очень полезен или необходим.

Вместо этого вы можете просто предоставить набор функций C. Функции C не обязательно должны быть связаны с классом вообще. Поэтому подумайте о том, чтобы сделать что-то вроде этого:

static NSString* someStaticStateVariable;

void someFunction(void)
{
    NSLog(@"Do Some Work");
}

Функции могут быть в отдельной паре .h/.m или могут быть включены в .h/.m для существующего класса, если имеет смысл сделать это (как правило, если функции тесно связаны с проблемами этого класса).