2012-01-19 2 views
0

У меня есть оператор if, который передается этому файлу реализации через NSUserDefaults, как показано ниже.если оператор выполняется до того, как его условные переменные установлены

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
NSString *code = [defaults objectForKey:@"codeKey"]; 
selectedCodeLocal = code; 

После этого кода, чтобы восстановить строковую переменную, у меня есть, если заявление:

if (selectedCodeLocal == @"1") 
    textView.text = "@blah blah blah"; 
else 
    textview.text = "@abcdefghijklmnop"; 

Когда я построить и запустить, оказывается, что переменная передается, но он никогда не передается, пока ПОСЛЕ выполнения задания if.

У меня есть NSLog вокруг этого кода, которые возвращают строчную переменную selectedCodeLocal, а значение переменной всегда на один шаг. (Например, если я сначала передаю его как 4, а затем передам его как 1, он будет возвращен в журнале первым как 1, затем как 4, затем как 1) Извините, если я вас смутил.

UPDATE:

- (void)viewDidLoad { 

[super viewDidLoad]; 
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
[defaults synchronize]; 
selectedCodeLocal = [defaults objectForKey:@"codeKey"]; 
NSLog(@"set: %@",selectedCodeLocal); 

self.navigationItem.title = selectedCodeLocal; 

[textView setClipsToBounds:NO]; 
[textView setEditable:NO]; 
[textView setFrame:CGRectMake(20, 100, 50, 50)]; 

if ([selectedCodeLocal isEqualToString:@"100"]) 
    textView.text = @"abc"; 
else 
    textView.text = @"xyz"; 

} 

NSLog по-прежнему отображается старое значение selectedCodeLocal.

UPDATE: здесь, где установлен этот ключ. (в предыдущем виде)

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

//Get the selected code 

NSString *selectedCode = nil; 

if(searching) 
    selectedCode = [copyListOfItems objectAtIndex:indexPath.row]; 
else { 

    NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section]; 
    NSArray *array = [dictionary objectForKey:@"codesKey"]; 
    selectedCode = [array objectAtIndex:indexPath.row]; 
} 

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
[defaults setObject:selectedCode forKey:@"codeKey"]; 
[defaults synchronize]; 

} 

@Firoze Lafeer: Ответит ли это на ваш вопрос? storyboard

+0

Я изменил код так: 'NSUserDefaults * дефолты = [NSUserDefaults standardUserDefaults];' ' selectedCodeLocal = [по умолчанию objectForKey: @ "codeKey"];' ' [по умолчанию синхронизирует],' ' NSLog (@ "set:% @", selectedCodeLocal); ' Файл журнала по-прежнему показывает, что строковая переменная' selectedCodeLocal' не была обновлена ​​до следующего запуска этой части кода. (это всегда на 1 шаг позади) –

+0

[defaults syncrhonize] должен быть выше selectedCodeLocal –

+0

Это по-прежнему один шаг назад; \ я поместил '[defaults synchronize]' before' selectedCodeLocal = [defaults objectForKey: @ "codeKey"]; 'и после' NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; ' –

ответ

1

С раскадровки, и SEGUE прикрепленную к Tableview клетки, ваш tableView:didSelectRowAtIndexPath будет называться после новой контроллер просмотра загружен и нажат.

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

Правильное время для настройки любых данных, необходимых для контроллера подробного представления, находится в методе prepareForSegue:sender: на вашем контроллере таблицы. tableView:didSelectRowAtIndexPath: слишком поздно, если вы используете сегу на столе в раскадровке.

Другие мысли:

  • Все остальное является правильным, что вы должны использовать isEqualToString:, не ==. Тот факт, что последний работает на вас, действительно является случайностью реализации. Вам нужно, чтобы сделать правильную вещь и не зависеть от этого. Использование '==' (это сравнение указателей в этом случае) неверно.

  • Говоря правильно, вы должны подумать, действительно ли selectedCode относится к вашим предпочтениям пользователя (NSUserDefaults). Было бы намного проще сделать это @property контроллера подробного представления и установить это свойство непосредственно в вашем методе prepareForSegue:sender:.

Надеюсь, что это поможет.

+0

Большое спасибо, вы давно открыли мне глаза, так как я прочитал этот ответ. Если бы я мог принять это дважды, я бы это сделал. –

+0

О, я рад, что это помогло. Удачи с приложением! –

1

Я думаю, что ваша проблема в том, что старый любимый, строка сравнение.

Я думаю, что вы имеете в виду:

if ([selectedCodeLocal isEqualToString:@"1"]) 

или что-то вроде этого (это было в течение года, так как я написал Obj-C).

+0

это похоже на лучший способ записать условие оператора if, хотя работа '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Любые другие идеи? –

+2

'isEqualToString:' не лучший способ написать оператор if. Это правильный путь. Оператор равенства, '==', будет проверять, указывают ли два указателя на один и тот же объект. Это редко случается при работе со строками. Метод 'isEqualToString:' фактически сравнивает * содержимое * указателей, которые вы хотите, в большинстве случаев, вероятно, захотите сделать. –

+1

Он прав, вы знаете. – Joe

2

При изменении значения в NSUserDefaults выполните синхронизацию. Например

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
[defaults setObject:@"4" forKey:@"codeKey"]; 
[defaults synchronize]; 

также

if (selectedCodeLocal == @"1") 

должно быть действительно

if (selectedCodeLocal isEqual:@"1") 
+0

инструкция if отлично работает, спасибо. Но 'NSUserDefaults' по-прежнему не устанавливает строчную переменную' selectedCodeLocal' во времени. –

+0

один быстрый вопрос, если вы манипулируете им напрямую, зачем вам нужно использовать NSUSerDefaults? На данный момент я не вижу ничего плохого в коде, возможно, если вы можете опубликовать больше кода –

+0

Я передаю строку из другого представления, поэтому я использую 'NSUserDefaults'. Эта строка определит (через оператор if), как установить текстовое свойство UITextView в этом новом 'View' –