Шаблон «Одиночка» (Singleton)

Для чего это нужно

Гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа. Существенно то, что можно пользоваться именно экземпляром класса, так как при этом во многих случаях становится доступной более широкая функциональность. Например, к описанным компонентам класса можно обращаться через интерфейс.
Если говорить проще — мы создаем место для хранения глобальных переменных и глобальных функций (методов), что очень полезно для решения задач, где следование догмам ООП и TDD только мешает.

Рассмотрим создание и использование глобальных переменных и функций.
Создаем Класс Global для их хранения (он имеет несколько не привычный способ инициализации):

Global.h

@interface Global : NSObject {
}

@property (assign) int globalVar;
 
+ (Global *)sharedInstance;
-(int)globalSumm:(int)a add:(int)b
 
@end

У реализации есть 2 варианта

Global.m (вариант 1)

@implementation Global
static Global *_sharedInstance = nil;
 
+(Global *)sharedInstance 
{
    @synchronized(self) 
    {
        if (!_sharedInstance) 
        {
            _sharedInstance = [[Global alloc] init];
        }
    }
    return _sharedInstance;
}

-(int)globalSumm:(int)a add:(int)b
{
    return a + b;
}
 
@end

Global.m (вариант 2) (только для OS X 10.6+, iOS 4.0+)

@implementation Global
 
+ (Global *)sharedInstance 
{
    static dispatch_once_t pred;
    static Global *sharedInstance = nil;
 
    dispatch_once(&pred, ^{ sharedInstance = [[self alloc] init]; });
    return sharedInstance;
}

-(int)globalSumm:(int)a add:(int)b
{
    return a + b;
}
 
@end

Как видите, все отличие заключается только в реализации метода класса sharedInstance. Какой из вариантов использовать — дело вкуса. Очень много всего наговорено о том, что-же лучше. Единого мнения нет. Решайте сами.

Как это использовать

Теперь посмотрим правила использования на примере вызова внутри собственного класса.

MyClass.h

#import "Global.h"
@interface MyClass : NSObject {
}
@end

MyClass.m

@implementation MyClass
 
-(void)myMethod
{
    // Присвоение значения глобальной переменной
    [[Global sharedInstance] setGlobalVar:10];
    
    // получение значения из глобальной переменной
    int a = [[Global sharedInstance] globalVar];
    
    // вызов глобальной функции (метода)
    int summ = [[Global sharedInstance] globalSumm:10 add:20];
}
 
@end

Как видите, все очень просто и привычно. Мы создали глобальные переменные и функции, вписав их в рамки и правила ООП. Кроме этого — такая модель хорошо совместима с ARC.

Добавить комментарий


пять − три =

Ваш e-mail не будет доступен другим пользователям. Все поля обязательны для заполнения.