синглтон класс в объективе-C - PullRequest
0 голосов
/ 26 марта 2011

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

@interface LocationManager : NSObject <CLLocationManagerDelegate>{
    NSDate *enter;
    NSDate *exit;
    CLLocationManager * manager;

}

@property (nonatomic, retain) NSDate * enter;
@property (nonatomic, retain) NSDate * exit;

- (BOOL)registerRegionWithLatitude:(double)latitude andLongitude:(double)longitude;
+ (LocationManager *)instance;

@end


#import "LocationManager.h"

@implementation LocationManager
@synthesize enter;
@synthesize exit;

#pragma mark - CLLocationManager delegate
static LocationManager *gInstance = NULL;


+ (LocationManager *)instance
{
    @synchronized(self)
    {
        if (gInstance == NULL)
            gInstance = [[self alloc] init];
    }
    return(gInstance);
}

@end

Это правильно?Так что все, что мне нужно сделать, чтобы получить доступ к этому, это просто вызвать экземпляр?Внутри LocationManager я также хочу иметь только один CLLocationManager, называемый manager. Однако, где я могу его инициализировать, чтобы у меня был только один?Могу ли я сделать следующее?В большинстве других одноэлементных примеров нет переменных в классе, поэтому я запутался

+ (LocationManager *)sharedLocationManager
{
    @synchronized(self)
    {
        if (lm == NULL){
            lm = [[self alloc] init];
            lm.manager = [[CLLocationManager alloc] init];
            lm.manager.delegate = lm;
        }
    }
    return(lm);
}

Ответы [ 4 ]

1 голос
/ 26 марта 2011

В основном - да.
Просто пара небольших вещей:
static LocationManager *gInstance = NULL;
вместо NULL, вы должны использовать nil, это соглашение в Objective-C.

Вы также должны перезаписать alloc, new, copyWithZone: и mutableCopyWithZone:.От Бака / Яктмана: «Шаблоны дизайна какао», с.153:

+ (id)hiddenAlloc  
{
  return [super alloc];
}

+ (id)new
{
  return [self alloc];
}

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

- (id)copyWithZone:(NSZone *)zone
{
  [self retain];
  return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
  return [self copyWithZone:zone];
}

Таким образом, ваш одноэлементный объект не может быть скопирован.Вам нужно вызвать hiddenAlloc из вашего instance метода (кстати, метод доступа к объекту Singleton часто называется sharedInstance в Objective-C).

0 голосов
/ 04 июня 2012

Поскольку фабричный метод "instance" является методом уровня класса, блок @synchronized должен быть @synchronized ([Класс LocationManager]) { //}

0 голосов
/ 26 марта 2011

На самом деле, уже существует проверенный способ создания синглетонов.Загрузите файл SynthesizeSingleton.h (из статьи Какао с любовью ).Он содержит огромное количество кода препроцессора, который сгенерирует любой синглтон для вас.Нажмите на статью для более подробной информации.

0 голосов
/ 26 марта 2011

Для других одноэлементных стилей с их плюсами и минусами, проверьте этот вопрос .

Лично я предпочитаю этот стиль (скопировано с одного из ответов по этой ссылке):

static MySingleton *sharedSingleton;

+ (void)initialize
{
    static BOOL initialized = NO;
    if(!initialized)
    {
        initialized = YES;
        sharedSingleton = [[MySingleton alloc] init];
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...