Синглтон в iOS 5?
Привет, у меня была реализация предыдущих версий iOS для singleton следующим образом:
.h файл
@interface CartSingleton : NSObject
{
}
+(CartSingleton *) getSingleton;
.m file
@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;
}
Может ли кто-нибудь, кто имеет опыт, направить меня.
Я новичок и полностью запутался между старой реализацией iOS Синглтона и новой и которая является правильной?
Спасибо большое
Ответы
Ответ 1
Строго говоря, вы должны использовать:
+ (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 и создать другой экземпляр.
Объяснение: Метод экземпляра находится на уровне класса и является вашим основным методом доступа, чтобы получить ссылку на singleton. Метод просто использует встроенную очередь dispatch_once(), которая будет выполнять только один блок. Как среда выполнения гарантирует, что блок выполняется только один раз? Используя предикат, который вы предоставляете (типа dispatch_once_t). Этот низкоуровневый вызов гарантирует, что даже если есть несколько потоков, пытающихся вызвать его, только один преуспевает, остальные ждут, пока первый не будет выполнен, а затем вернется.
Причина, по которой мы переопределяем allocWithZone, заключается в том, что alloc вызывает allocWithZone, передающий nil как зону (для зоны по умолчанию). Чтобы предотвратить изгнание кода изгоев и инициализацию другого экземпляра, мы переопределяем allocWithZone, чтобы возвращаемый экземпляр был уже инициализированным синглтоном. Это предотвращает создание второго экземпляра.
Ответ 2
Фрагмент 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 (но это безопасно таким образом).
Ответ 3
Singleton - это особый класс, в котором существует только один экземпляр класса для текущего процесса. (В случае приложения iPhone один экземпляр используется во всем приложении.) Некоторые примеры в UIKit - это [UIApplication sharedApplication] (который возвращает единственный экземпляр самого приложения) и [NSFileManager defaultManager] (который возвращает экземпляр файлового менеджера). Синглтоны могут быть простым способом совместного использования данных и общих методов во всем приложении.
Вместо создания экземпляров одноэлементного класса с помощью alloc/init вы вызовете метод класса, который вернет объект singleton. Вы можете назвать метод класса любым, но обычной практикой является вызов его sharedName или defaultName.
Пожалуйста, проверьте связь с лучшим ответом
: http://www.idev101.com/code/Objective-C/singletons.html