NSUserDefaults не сохраняется - PullRequest
       35

NSUserDefaults не сохраняется

0 голосов
/ 23 февраля 2012

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

В моем NewEntry.m у меня есть:

-(IBAction)saveButton:(id)sender {    

    int i = selectedSegment.selectedSegmentIndex;    

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

    [userDefaults setInteger:i  forKey:@"category"];

    [userDefaults synchronize];

    if (selectedSegment.selectedSegmentIndex == 0) {
        [userDefaults setObject:titlefield.text forKey:@"titletexthomework"];
        [userDefaults setObject:detailstextfield.text forKey:@"detailshomework"];
    }
    else if(selectedSegment.selectedSegmentIndex == 1) {
        [userDefaults setObject:titlefield.text forKey:@"titletextprojects"];
        [userDefaults setObject:detailstextfield.text forKey:@"detailsprojects"];

    }
    else if (selectedSegment.selectedSegmentIndex == 2){
        [userDefaults setObject:titlefield.text forKey:@"titletextappointments"];
        [userDefaults setObject:detailstextfield.text forKey:@"detailsappointments"];
    }
    else if (selectedSegment.selectedSegmentIndex == 3){
        [userDefaults setObject:titlefield.text forKey:@"titletextevents"];
        [userDefaults setObject:detailstextfield.text forKey:@"detailsevents"];

    }

    else if (selectedSegment.selectedSegmentIndex == 4){
        [userDefaults setObject:titlefield.text forKey:@"titletexttodolist"];
        [userDefaults setObject:detailstextfield.text forKey:@"detailstodolist"];
    }

    [userDefaults synchronize];
    NSLog(@"selected segment %i", i);
}

тогда в моих Projects.m у меня есть:

-(void)viewDidLoad
{
    [super viewDidLoad];    

    categoryselected = [[NSUserDefaults standardUserDefaults] integerForKey:@"category"];
    NSLog(@"category selected %i", categoryselected);        

    titlestring = [[NSUserDefaults standardUserDefaults]  objectForKey:@"titletextprojects"];
    detailsstring = [[NSUserDefaults standardUserDefaults] objectForKey:@"detailsprojects"];        

    tabledata = [[NSArray alloc] initWithObjects:titlestring, nil];
    tablesubtitles = [[NSArray alloc] initWithObjects:detailsstring, nil];    
}

//-------------------------------------------------------
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{    
    UITableViewCell *cell = nil;

    cell = [tableView dequeueReusableCellWithIdentifier:@"projectscell"];   

    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"projectscell"];
    }

    cell.textLabel.text = [tabledata objectAtIndex:indexPath.row];
    cell.detailTextLabel.text = [tablesubtitles objectAtIndex:indexPath.row];
    cell.textLabel.font = [UIFont systemFontOfSize:14.0];
    cell.textLabel.backgroundColor = [ UIColor clearColor ];
    cell.detailTextLabel.backgroundColor = [UIColor clearColor];

    return cell;
}

******* UPDATE **************

Я изменил часть, которая заполняет таблицу, на статическую строку следующим образом:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
tabl = [[NSArray alloc] initWithObjects:@"hello", nil];
NSLog(@"tabledata %@", tabledata );
tab = [[NSArray alloc] initWithObjects:@"hello2", nil];
NSLog(@"details %@", tablesubtitles);



UITableViewCell *cell = nil;

cell = [tableView dequeueReusableCellWithIdentifier:@"projectscell"];


if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"projectscell"];

}
cell.textLabel.text = [tabl objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [tab objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont systemFontOfSize:14.0];
cell.textLabel.backgroundColor = [ UIColor clearColor ];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];

И таблица по-прежнему отображается пустой.Спасибо за помощь.

Ответы [ 4 ]

3 голосов
/ 23 февраля 2012

Синхронизация вызова ПОСЛЕ установки любых значений.

1 голос
/ 24 февраля 2012

Я не замечаю ничего плохого в коде NSUserDefaults, по сути, хотя он захватывает значения только при загрузке представления, а не при обновлении значений.Чтобы исправить это, вы можете отправить уведомление, чтобы все другие заинтересованные контроллеры представления знали об изменении состояния.В - [NewEntry saveButton:], после сохранения значений в NSUserDefaults, добавьте

[[NSNotificationCenter defaultCenter] postNotificationName:@"ValuesChanged"
                                                    object:self];

, чтобы отправить уведомление.Где-нибудь в Projects.m (init - хорошее место), подпишитесь на уведомление с помощью

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(valuesChanged:)
                                             name:@"ValuesChanged"
                                           object:nil];

. Это заставит центр уведомлений вызывать ваш метод valuesChanged: при публикации уведомления.Мы будем обновлять пользовательский интерфейс почти так же, как в viewDidLoad, поэтому давайте выделим этот код:

- (void)reloadData
{
    categoryselected = [[NSUserDefaults standardUserDefaults] integerForKey:@"category"];
    NSLog(@"category selected %i", categoryselected);

    // XXX - note the following strings are returned autoreleased. If they're
    // stored in ivars, it's a good idea to retain them, even though we know
    // they're retained by the arrays below.

    titlestring = [[NSUserDefaults standardUserDefaults]  objectForKey:@"titletextprojects"];
    detailsstring = [[NSUserDefaults standardUserDefaults] objectForKey:@"detailsprojects"];

    [tabledata release];
    tabledata = [[NSArray alloc] initWithObjects:titlestring, nil];

    [tablesubtitles release];
    tablesubtitles = [[NSArray alloc] initWithObjects:detailsstring, nil];

    [tableView reloadData];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self reloadData];
}

- (void)valuesChanged:(NSNotification*)notification
{
    [self reloadData];
}

И последнее: все эти строки, ключи для NSUserDefaults иимя уведомления @ "ValuesChanged"?Они действительно должны быть определены как константы, так что есть только одна «истинная» версия строки.Во-первых, это избавляет вас от случая, когда вы случайно ошиблись в одном месте и удивляетесь, почему значения не синхронизируются.Это может занять несколько часов, чтобы понять, что происходит, когда это происходит.(Исходя из опыта здесь.) Во-вторых, компилятор может проверить, что у вас есть правильное имя, и автозаполнение IDE (когда оно действительно работает) может предложить вам ключевые имена.Вы можете сделать #define в общем заголовке где-нибудь

#define kDefaultsKeySelectedCategory @"category"

, и компоновщик , вероятно, создаст один постоянный экземпляр строки, совместно используемой для каждого места, где он используется.Тем не менее, если я изменю строку в этом определении и Xcode будет капризным и не перекомпилирует каждый исходный файл, который его использует, мы вернемся к случаю, когда ключ пишется по-разному в разных местах.Не хорошо.Более причудливый способ сделать это, обеспечивающий только одну копию строки, - объявить

extern NSString* const kDefaultsKeySelectedCategory;

в заголовочном файле, а затем

NSString* const kDefaultsKeySelectedCategory = @"category";

в .m файле.Еще одна вещь, которая мне нравится в этом, это то, что она скрывает детали реализации.Никому не нужно знать, что это за конкретная строка, поэтому ее не должно быть в заголовочном файле.

0 голосов
/ 15 июля 2016

У меня была проблема с установкой NSUserDefaults, даже если вы сразу после этого используете команду синхронизации. Моя проблема была в том, что приложение было переименовано, и я считаю, что NSUserDefaults не синхронизировал местоположение правильно. Я удалил приложение и переустановил его из XCode, и это сработало. Я предполагаю, что это немного особый случай, но если что, попробуйте это.

0 голосов
/ 22 октября 2013

У меня была такая же проблема, когда я тестировал свое приложение, где, если я использую Stop в отладчике, а затем перезапускаю свое приложение, NSUserDefaults неправильно показывал старый список. Это произошло не с операцией вставки, а с удалением.

Если я использую кнопку «Домой» для выхода из приложения (убить его), а затем снова запускаюсь, мои NSUserDefaults были правильными.

Алек 23 февраля '12 в 17:13 также упоминал об этом в предыдущем комментарии.

...