Синглтон не сохраняется из делегата приложения в другой контроллер представления - PullRequest
2 голосов
/ 29 июня 2011

По этой ссылке: Как архивировать два объекта с помощью NSKeyedArchiever? Я могу заархивировать массив и одноэлементный объект. Я могу заархивировать и правильно разархивировать его в didFinishLaunchingWithOptions.

Однако мой одноэлементный объект не сохраняется после делегата приложения. В следующем контроллере представления синглтон-переменные возвращаются к значениям по умолчанию, хотя в didFinishLaunchingWithOptions я сделал NSLog и проверил. Вот пример,

В приложении didFinishLaunchingWithOptions:

Singleton *singleton = [Singleton sharedSingleton];
NSData *data = [NSData dataWithContentsOfFile:path];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
singleton = [unarchiver decodeObjectForKey:@"singleton"];
[unarchiver finishDecoding];

NSLog(@"singleton sorting after decode: %@", [singleton sort]); // выход: алфавит

Затем я выделяю / инициализирую viewController и устанавливаю его в качестве корневого контроллера представления для моего контроллера навигации:

navController = [[UINavigationController alloc] initWithRootViewController:viewController];

В viewController -> viewWillAppear,

Я вызываю функцию сортировки: [самостоятельная сортировка ...];

А в функции сортировки я вызываю синглтон-класс: Синглтон *singleton = [Singleton sharedSingleton]; Но теперь NSLog(@"singleton sort: %@", [singleton sort]); // вывод: количество НЕ алфавит

Я могу опубликовать свой синглтон-код, но я знаю, что он работает. Фактически, в моем контроллере представления настроек, если я изменю переменную [singleton sort], она сохранится во всех контроллерах представления.

Меня смущает, почему мой одноэлементный объект не сохраняется от делегата приложения до моих контроллеров представления. Любые советы / подсказки приветствуются.

Спасибо !!!

РЕДАКТИРОВАТЬ: реализация класса Singleton

In Singleton.m:

static Singleton *shared = NULL;

+ (id)sharedSingleton
{
    @synchronized(self)
    {
        if ( !shared || shared == NULL )
        {
            // allocate the shared instance, because it hasn't been done yet
            NSLog(@"Allocating Singleton...");
            shared = [[Singleton alloc] init];
        }
        return shared;
    }
}


- (id)init
{
    if ( self = [super init] )
    {
        sort = [[NSString alloc] initWithString:@"amount"];
        showTutorial = YES;
    }
    return self;    
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    [super init];
    [self setSort:[aDecoder decodeObjectForKey:@"sort"]];
    [self setShowTutorial:[aDecoder decodeBoolForKey:@"showTutorial"]];

    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:sort forKey:@"sort"];
    [aCoder encodeBool:showTutorial forKey:@"showTutorial"];
}

Ответы [ 5 ]

2 голосов
/ 29 июня 2011

Вы также назначили объект автоматического выпуска локальной переменной.Этот объект выйдет из области видимости (то есть будет освобожден) в следующий раз через цикл обработки событий.

singleton = [unarchiver decodeObjectForKey:@"singleton"];
2 голосов
/ 29 июня 2011

Я думаю, что вы ошиблись синглтон-шаблоном.

Вы создаете его в коде

Singleton *singleton = [Singleton sharedSingleton];

, что правильно, но делаете

singleton = [unarchiver decodeObjectForKey:@"singleton"];

не имеет смысла для синглтона вообще.Вообще говоря, вы не хотите создавать экземпляры своих синглетонов из перьев.

2 голосов
/ 29 июня 2011

В вашем коде вы просто обновляете значение одноэлементного указателя в текущем контексте, а не экземпляр sharedSingleton

Попробуйте создать метод в своем классе Singleton, который обновит класс singleton с помощью объекта unarchiverнапример:

[[Singleton sharedSingleton] loadArchive:unarchiver];

или (что лучше, я думаю) переместить ваш код в функцию инициализации Singleton.

1 голос
/ 29 июня 2011

Ваш singleton указатель - это просто локальная переменная, которая изначально указывает на общий экземпляр Singleton.Затем вы приходите и изменяете значение singleton так, чтобы оно указывало на объект, который вы декодируете из unarchiver. Установка этого локального указателя на новый Singleton не изменяет общий экземпляр Singleton и не изменяет значение глобального shared.

Кроме того, я думаю,Вы можете неправильно понять шаблон синглтона.Предполагается, что шаблон синглтона используется, когда не может быть разрешено существование более одного экземпляра класса.Синглтоны часто используются, потому что к ним легко получить доступ во всем мире, но многие умные люди считают использование синглетонов по этой причине злоупотреблением шаблоном.Вы можете согласиться или не согласиться по этому вопросу, но факт заключается в том, что вы создаете два экземпляра вашего класса Singleton, и по определению это означает, что ваш класс Singleton не является истинной реализацией шаблона проектирования Singleton.

0 голосов
/ 29 июня 2011

Большинство комментариев, приведенных ниже, указывают на правильное направление в том, что в моем исходном коде я создавал два экземпляра класса Singleton.И я осознаю свою глупость, так что вот код, который работает:

Singleton *singleton = [unarchiver decodeObjectForKey:@"singleton"];

Затем, используйте единственный экземпляр mySingleton:

Singleton *mySingleton = [Singleton sharedSingleton];
[mySingleton setSort:[singleton sort]];

Итак, таким образом, анархивер тянетэкземпляр одноэлементного объекта, который автоматически высвобождается, но значение установлено в настоящий класс Singleton.

Примечание: в некоторых комментариях упоминается, что я, возможно, не использую класс Singleton должным образом, и, вероятно, нет.Я не эксперт в этом.Я просто хочу что-то сохранить и вернуть обратно, когда приложение завершится.Если это поможет вам, отлично.Если нет, оставьте комментарий, чтобы помочь всем нам учиться лучше.Если я поправлюсь и узнаю больше, возможно, я обновлю этот пост.

Спасибо за все комментарии.С ними все в порядке.Я проголосовал за всех из них.

...