Синглтон в iOS 5? - PullRequest
       11

Синглтон в iOS 5?

11 голосов
/ 10 января 2012

Привет У меня была реализация предыдущих версий iOS для синглтона следующим образом:

.h файл

@interface CartSingleton : NSObject 
{

}
+(CartSingleton *) getSingleton;

.m файл

@implementation CartSingleton

static CartSingleton *sharedSingleton = nil;

+(CartSingleton *) getSingleton
{
    if (sharedSingleton !=nil)
       {
        NSLog(@"Cart has already been created.....");
        return sharedSingleton;
       }
    @synchronized(self)
   {
    if (sharedSingleton == nil)
       {
        sharedSingleton = [[self alloc]init];
        NSLog(@"Created a new Cart");
       }
   }
    return sharedSingleton;
}
//==============================================================================
+(id)alloc
{
    @synchronized([CartSingleton class])
   {
    NSLog(@"inside alloc");
    NSAssert(sharedSingleton == nil, @"Attempted to allocate a second instance of a singleton.");
    sharedSingleton = [super alloc];
    return sharedSingleton;
   }

    return nil;
}

//==============================================================================
-(id)init
{
    self = [super init];
}

Однако в Интернете я вижу, что люди реализовали шаблон проектирования Singleton, используя этот код:

+ (id)sharedInstance
{
  static dispatch_once_t pred = 0;
  __strong static id _sharedObject = nil;
  dispatch_once(&pred, ^{
    _sharedObject = [[self alloc] init]; // or some other init method
  });
  return _sharedObject;
}

Может ли кто-то, кто имеет опыт, направлять меня. Я новичок и полностью сбит с толку между старой реализацией Singleton в iOS и новой версией?

Большое спасибо

Ответы [ 3 ]

19 голосов
/ 19 июля 2012

Строго говоря, вы должны использовать:

+ (MySingleton*) instance {
     static dispatch_once_t _singletonPredicate;
     static MySingleton *_singleton = nil;

     dispatch_once(&_singletonPredicate, ^{
        _singleton = [[super allocWithZone:nil] init];
     });

     return _singleton;
 }

 + (id) allocWithZone:(NSZone *)zone {
      return [self instance];
 }

Теперь вы гарантируете, что нельзя вызывать alloc / init и создать другой экземпляр.

Объяснение: Метод экземпляра находится на уровне классаи ваш основной метод доступа, чтобы получить ссылку на синглтон.Метод просто использует встроенную очередь dispatch_once (), которая будет выполнять блок только один раз.Как среда выполнения гарантирует, что блок выполняется только один раз?Используя предоставленный вами предикат (типа dispatch_once_t).Этот низкоуровневый вызов гарантирует, что даже если есть несколько потоков, пытающихся вызвать его, успешным будет только один, остальные ждут, пока первый не будет выполнен, а затем возвращаются.

Причина, по которой мы переопределяем allocWithZone, заключается в том, что allocвызывает allocWithZone, передавая nil как зону (для зоны по умолчанию).Чтобы не допустить мошеннического кода для выделения и инициализации другого экземпляра, мы переопределяем allocWithZone, чтобы передаваемый экземпляр был уже инициализированным синглтоном.Это препятствует созданию второго экземпляра.

9 голосов
/ 10 января 2012

Фрагмент dispatch_once функционально идентичен другому. Вы можете прочитать об этом на http://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man3/dispatch_once.3.html.

Это то, что я использую для одиночных игр:

+ (MySingleton*) getOne {
    static MySingleton* _one = nil;

    @synchronized( self ) {
        if( _one == nil ) {
            _one = [[ MySingleton alloc ] init ];
        }
    }

    return _one;
}

ПРИМЕЧАНИЕ. В большинстве случаев вам даже не нужно использовать @synchronized (но это безопасно).

0 голосов
/ 19 августа 2014

Синглтон - это особый вид класса, в котором для текущего процесса существует только один экземпляр класса.(В случае приложения для iPhone один экземпляр является общим для всего приложения.) Некоторыми примерами в UIKit являются [UIApplication sharedApplication] (который возвращает единственный экземпляр самого приложения) и [NSFileManager defaultManager] (который возвращаетэкземпляр файлового менеджера).Singletons могут быть простым способом обмена данными и общими методами по всему вашему приложению.

Вместо того, чтобы создавать экземпляры одноэлементного класса с помощью alloc / init, вы вызовете метод класса, который вернет одноэлементный объект.Вы можете назвать метод класса как угодно, но обычная практика - называть его sharedName или defaultName.

Пожалуйста, проверьте ссылку с лучшим ответом : http://www.idev101.com/code/Objective-C/singletons.html

...