2016-07-04 3 views
2

Я пытаюсь разобраться с компилятором в случае дополнительных значений. Задача очень проста, мой func устанавливает значения по умолчанию для пользователей в tableview. Если пользователь запускает приложение в первый раз, он устанавливает значения по умолчанию. Установка значений по умолчанию работает отлично (проверено с журналом печати), но кокетливые причины:Необязательные NSUserDefaults в Swift

fatal error: unexpectedly found nil while unwrapping an Optional value

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

func getFiltersSetts() -> [String] { 
    let userDefs = NSUserDefaults.standardUserDefaults() 
    var defsArray = [String]() 
    if (userDefs.objectForKey("gender") != nil) { 
     defsArray.append((userDefs.objectForKey("gender")?.stringValue)!) 
     defsArray.append((userDefs.objectForKey("age")?.stringValue)!) 
     defsArray.append((userDefs.objectForKey("online")?.stringValue)!) 
    } 
    else { 
     userDefs.setObject("Male", forKey: "gender") 
     userDefs.setObject("21-30", forKey: "age") 
     userDefs.setObject("Online", forKey: "online") 
    } 
    return defsArray 
} 
+0

Прежде всего отлаживать, какой объект является нулевым и вызывает ошибку при разворачивании. – Wujo

ответ

3

Вы сила разворачивает свои УСТРОЙСТВА, и вы должны получить их как строки, перед добавлением их в массив ,

уборщик способ установить по умолчанию будет сливаться в развёртках ваших дополнительных опций, попробуйте следующий подход:

func getFiltersSetts() -> [String] { 
    let userDefs = NSUserDefaults.standardUserDefaults() 
    var defsArray = [String]() 
    defsArray.append(userDefs.stringForKey("gender") ?? "Male") 
    defsArray.append(userDefs.stringForKey("age") ?? "21-30") 
    defsArray.append(userDefs.stringForKey("online") ?? "Online") 
    return defsArray 
} 

Код выше использует Coalesce (??) оператор. Если ваш опциональный, скажем userDefs.stringfForKey («gender»), возвращает nil, оператор coalesce будет использовать значение по умолчанию «Мужской».

Затем вы можете сохранить свои настройки по умолчанию (или создать их), если они не были установлены ранее.

Кроме того, стоит заметить, что вы должны разворачивать свои опционы, используя , если давайте обозначить. Вместо сравнения, если его! = Nil, так как это не даст вам силы развернуть их внутри блока кода.

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

+1

Удивительная языковая особенность! –

0

Вы можете создать ключ по умолчанию «firstBootCompleted». Затем используйте:

let defaults = NSUserDefaults.standardUserDefaults() 
if (defaults.boolForKey("firstBootCompleted") == false) { 
    defaults.setObject(true, forKey: "firstBootCompleted") 

    // Initialize everything for your first boot below 

} else { 

    // Initialize everything for not your first boot below 

} 

Причина это работает в том, что boolForKey возвращает false, когда объект для ключа nil

0

Вы сохраняете все значение как String, а затем во время извлечения вы снова типаж значение в String

userDefs.objectForKey("gender")?.stringValue 

String не может конвертировать в String снова.

пытаются получить доступ в

userDefs.stringForKey("gender") 
2

компании Apple настоятельно рекомендует, чтобы установить значения по умолчанию с помощью registerDefaults из NSUserDefaults.

Как можно скорее (по крайней мере, перед первым использованием) установить значения по умолчанию, например, в applicationDidFinishLaunching:

let userDefs = NSUserDefaults.standardUserDefaults() 
let defaultValues = ["gender" : "Male", "age" : "21-30", "online" : "Online"] 
userDefs.registerDefaults(defaultValues) 

Значение по умолчанию считается пока новое значение не задано.

Выгода никогда не не имеет отношения к вариантам и типу.

func getFiltersSetts() -> [String] { 
    let userDefs = NSUserDefaults.standardUserDefaults() 
    return [userDefs.stringForKey("gender")!, 
      userDefs.stringForKey("age")!, 
      userDefs.stringForKey("online")!] 

} 

Принудительная разворачивание является 100% гарантией безопасности, потому что ни один из ключей никогда не может быть nil.

Пожалуйста, прочтите Registering Your App’s Default Preferences в Preferences and Settings Programming Guide

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