2015-07-06 4 views
3

Привет, мое приложение разбивается при первом запуске. Это мой код:Swift NSUserDefaults first time nil

let State = save.stringForKey("StateSave") 
let City = save.stringForKey("CitySave") 
let Vehicle = save.stringForKey("ModelNumberSave") 
let ExtensionPeriod = save.stringForKey("ExtensionPeriodChoosed") 
let Location = "Location" 


if ExtensionPeriod == nil { 
     let name = "" 
     var FieldChoosed: Void = save.setObject(name, forKey: "ExtensionPeriodChoosed") 
     save.synchronize() 

} 

save.synchronize() 
var DetailNames = ["\(State!)","\(City!)","\(Location)","\(Vehicle!)","\(ExtensionPeriod!)"] 

Я получаю nil на этой линии:

вар DetailNames = [ "(! State)", "(! Город)", "(Location)" "(Vehicle!)", "(ExtensionPeriod!)"]

На самом деле ExtensionPeriod является nil. Но я не понимаю, почему ... ExtensionPeriod is nil, но с кодом, который я пишу, ExtensionPeriod будет как "", так что это не nil. Пожалуйста, помогите мне.

+0

func stringForKey (_ defaultName: String) -> String? –

ответ

8

возвращает nil, когда уже не было сохраненного значения.

Вам необходимо указать свои значения по умолчанию. Самый простой способ сделать это с ?? оператором, который заменяет nil с другим значением:

let State = save.stringForKey("StateSave") ?? "-" 

Некоторые общие советы: вы должны прекратить использовать ! так много. Обычно, когда что-то возвращается nil, это по уважительной причине - это может быть nil. Когда вы развернете его с помощью !, ваша программа выйдет из строя (с не очень полезной информацией о том, почему). Аналогично, это обычно плохой знак, если вы сравниваете значения с nil.

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

+0

, но если я не поставлю "!" текст будет отображаться как необязательный. нет? – markutus

+0

Существует множество способов развернуть дополнительные опции, которые более безопасны, чем '!'. Посмотрите http://stackoverflow.com/a/27623568/3925941 и http://stackoverflow.com/a/29717211/3925941 для некоторых примеров. –

1

Airspeed Velocity имеет хорошее решение для правильного пути выполнения того, что вы хотите сделать, но он действительно не объяснил, почему то, что вы сделали, не работает, поэтому я рассмотрю этот аспект этого вопроса.

if ExtensionPeriod == nil { 
    let name = "" 
    var FieldChoosed: Void = save.setObject(name, forKey: "ExtensionPeriodChoosed") 
    save.synchronize() 
} 

Этот блок кода не устанавливает ExtensionPeriod, поэтому ExtensionPeriod по-прежнему равен нулю. Все, что он делает, устанавливает значение для ключа «ExtensionPeriodChoosed» в NSUserDefaults больше не равно нулю. Однако локальная переменная ExtensionPeriod все еще имеет значение nil. ExtensionPeriod не просто волшебным образом указывает на переменную, хранящуюся в NSUserDefaults, так что при обновлении NSUserDefaults она автоматически обновляет переменную. Вместо этого он копирует переменную в момент ее создания.

Ниже приведен пример кода, который демонстрирует это:

NSUserDefaults.standardUserDefaults().setValue("string", forKey: "s") 
    NSUserDefaults.standardUserDefaults().synchronize() 
    var s = NSUserDefaults.standardUserDefaults().valueForKey("s") 

    NSUserDefaults.standardUserDefaults().setValue("string2", forKey: "s") 
    NSUserDefaults.standardUserDefaults().synchronize() 
    var y = NSUserDefaults.standardUserDefaults().valueForKey("s") 

    println(s) 
    println(y) 

выходы:

"строка"

"string2"

Для вашего кода для работы, если бы вы сохранили его в той же структуре (хотя вы действительно не должны), вы wo uld необходимо изменить ExtensionPeriod на var, а затем в вашем блоке if после синхронизации сохранения вам придется переназначить ExtensionPeriod для save.valueForKey («ExtensionPeriodChoosed»).

+0

Нет необходимости в 'synchronize()', если вы не попадете в одну из узких категорий, которые Apple определила там, где это было бы уместно. Это не одна из этих категорий. –

+0

@JonShier Fair, я просто сделал образец как можно ближе к оригинальному примеру OP. –

+0

Да, справедливо. –

1

Один из способов убедиться в том, что установлены по умолчанию ваши приложения, использовать функцию NSUserDefaultregisterDefaults(_: [NSObject : AnyObject]). В Objective-C я часто ставил метод класса + (void)initialize, но переопределение init() делегата приложения должно работать так же хорошо.

Смежные вопросы