Шаблон singleton в Objective-C

Я знаю два варианта реализации синглтона. Один из них - это создание объекта в функции инициализации + (void)initialize (эта функция вызывается автоматически, во время выполнения, когда классу отправляется первое сообщение). А другой, используя dispatch_once из Grand Central Dispatch.

Singleton с использованием initialize

Следует заметить, что этот метод полностью потокобезопасен. Пример создание объекта одиночки приведен ниже. В интерфейсе мы определяем метод класса: + (WidgetManager *)sharedManager, который будет возвращать указатель на наш объект. Обычно, при реализации синглтона, метод, возвращающий объект начинается с префикса shared. Для примера добавим свойство объекта типа NSString.

@interface WidgetManager : NSObject

+ (WidgetManager *)sharedManager;

@property (strong, nonatomic) NSString *string;

@end

В реализации класса, нам необходимо создать статическую переменную, которая будет указывать на наш одиночный объект. Реализация метода sharedManager:

@implementation WidgetManager

static WidgetManager *sharedManager;

+ (void)initialize
{
    if (self == [WidgetManager class]) {
        sharedManager = [[WidgetManager alloc] init];
    }
}

+ (WidgetManager *)sharedManager
{
    return sharedManager;
}

@end

Singleton используя dispatch_once

Функция dispatch_once гарантирует, что блок, который мы передаем ей выполнится только один раз, за все время работы нашего приложения. Эта функция также потокобезопасная. Таким образом, реализация синглтона немного сократиться, и у нас останется только один метод:

#import "WidgetManager.h"

@implementation WidgetManager

+ (WidgetManager *)sharedManager
{
    static WidgetManager *sharadManager;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        sharadManager = [[WidgetManager alloc] init];
    });
    return sharadManager;
}

@end

Наш синглтон готов. Можно сделать проверку следующим кодом:

WidgetManager *manager = [WidgetManager sharedManager];
manager.string = @"Shared string";

WidgetManager *newManager = [WidgetManager sharedManager];
NSLog(@"Shared string is %@", newManager.string);

Опубликовано: Апрель 25, 2013 ~ obj-c