Управление памятью Singleton (несколько классов) - PullRequest
0 голосов
/ 09 декабря 2011

У меня есть синглтон с именем Singleton, который управляет определенными переменными, необходимыми для меня в приложении.

Я использую View Controller HomeViewController, который инициализирует синглтон на viewDidLoad, а затем отправляет сообщение на сервер и получает информацию. Затем он берет эту информацию и анализирует ее с отдельным классом XMLParser.

Когда синтаксический анализ XMLParser завершен, он отправляет HomeViewController уведомление о том, что это сделано, а затем HomeViewController сбрасывает данные в NSLog.

В моем классе XMLParser я звоню [singleton setXX:XX], а затем NSLog(@"%@", [[singleton XX]description]);, который отлично выводит данные. Если я вернусь к HomeViewController (после уведомлений) и попытаюсь зарегистрировать те же самые данные, он вернет Null.

Я пытался не инициализировать синглтон в viewDidLoad и перемещать инициализацию до тех пор, пока не получу уведомление о том, что анализ завершен, но я все еще получаю Null. Есть идеи? Я уверен, что это как-то связано с управлением памятью (ARC, кстати), но я точно не знаю, где именно.

Редактировать: Вот мой Singleton код.

//.h
//...
@property (nonatomic, retain) NSArray *linkedList;
@property (nonatomic, retain) NSDictionary *sessionData;

+ (id)sharedSingleton;

//.m
static MySingleton *sharedSingleton = nil;

@implementation MySingleton

@synthesize linkedList, sessionData;
+ (id)sharedSingleton {
    @synchronized(self) {
        if (sharedSingleton == nil)
            sharedSingleton = [[self alloc] init];
    }
    return sharedSingleton;
}

Edit2: вот мои методы доступа синглтона и т. Д.

//XMLParser
- (id) init {
    self = [super init];
    if (self != nil) {
        if (!singleton) singleton = [[MySingleton alloc]init];
    }
    return self;
}
//...cut because no singleton access
//Closing Element
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"SessionData"])
    {
        NSLog(@"Completed with SessionData. ID:11116");
        [singleton setSessionData:sessionData];
        NSLog(@"SessionData Description: \n%@", [sessionData description]);
        [[NSNotificationCenter defaultCenter] postNotificationName:@"pushToScreen" object:nil];
        return;
    }
}

//HomeViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    singleton = [MySingleton sharedSingleton];
}
//...cut for useless code
//Then when notification received, it calls this selector
- (void)connect
{
    //singleton = [MySingleton sharedSingleton];
    NSLog(@"%@", [[singleton linkedList]description]);
}

Ответы [ 2 ]

2 голосов
/ 09 декабря 2011

Отправка [[MySingleton alloc] init] из другого класса полностью отрицает цель синглтона. Вы должны иметь доступ к синглтону только через ссылку на класс sharedSingleton. Вся логика, относящаяся к тому, был ли установлен экземпляр, заключена в синглтоне. Таким образом, вы уверены, что всегда получаете один и тот же экземпляр обратно.

В вашем случае вы создали новый экземпляр Singleton, полностью игнорируя общий экземпляр, который используется HomeViewController, в методе XMLParser s -init.

Ваш метод -parser:didEndElement:namespaceURI:qualifiedName: устанавливает данные сеанса для нового экземпляра Singleton, а не для общего экземпляра, доступ к которому осуществляется с помощью метода класса sharedInstance. Как только HomeViewController получает уведомление, он проверяет общий экземпляр, и свойства равны нулю, поскольку заполнен неправильный экземпляр. Удалите метод -init и singleton ivar из XMLParser и используйте вместо него только [Singleton sharedInstance].

1 голос
/ 09 декабря 2011

Какой код у вашего синглтона?Моя всегда выглядит примерно так:

BookDescriptorDataModel* BookDescriptorDataModel_instance;
+(BookDescriptorDataModel*)getInstance
{
    @synchronized(self)
    {
        if(!BookDescriptorDataModel_instance)
        {
            BookDescriptorDataModel_instance = [[BookDescriptorDataModel alloc] init];
            [BookDescriptorDataModel_instance load];
        }
    }
    return BookDescriptorDataModel_instance;
}

Кроме того, как вы храните свои данные?Моя выглядит примерно так:

@property (strong,nonatomic) NSDictionary* bookDescriptor;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...