Swift NSUserDefaults NSArray с использованием objectForKey

#ios #swift #nsuserdefaults

#iOS #swift #nsuserdefaults

Вопрос:

Я довольно новичок в Swift, и мне удалось изрядно застрять.

Я пытаюсь извлечь данные из NSUserDefaults и сохранить их в массиве ( tasks ):

 @lazy var tasks: NSArray = {
    let def = NSUserDefaults.standardUserDefaults()
    let obj: AnyObject? = def.objectForKey("tasks")
    return obj as NSArray
}()
  

Все, что я получаю, это предупреждение: EXE_BAD_INSTRUCTION в строке 3.

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

Теперь вместо константы используется var:

 @lazy var tasks: NSArray = {
    let def = NSUserDefaults.standardUserDefaults()
    var obj: AnyObject? = {
        return def.objectForKey("tasks")
    }()
    return obj as NSArray
}()
  

Ошибка теперь переместилась в строку возврата.

Комментарии:

1. Я не уверен, что вы можете присвоить nil константе. Что произойдет, если заменить let obj на var obj ?

2. Я попытался использовать var, теперь я получаю то же предупреждение в строке возврата (обновлено).

3. Добавить восклицательный знак к возвращаемому типу? NSArray! .

4. Похоже, это помогло, однако предупреждение изменилось: cl.ly/WQEK

5. @LordZsolt почему восклицательный знак? Поскольку objectForKey может возвращать nil, тип свойства должен быть необязательным, т. Е. заканчиваться вопросительным знаком ? .

Ответ №1:

Я думаю, проблема здесь в том, что вы пытаетесь привести nil к необязательному типу и вернуть его. Swift этого не допускает. Лучшим способом решения этой проблемы было бы следующее:

 @lazy tasks: NSArray = {
    let defaults = NSUserDefaults.standardUserDefaults()
    if let array = defaults.arrayForKey("tasks") as? NSArray {
        return array
    }
    return NSArray()
}
  

Использование if let синтаксиса Swift в сочетании с as? оператором позволяет назначать и безопасно приводить в одной строке. Поскольку ваш метод не возвращает необязательное значение, вы должны вернуть допустимое значение, если это приведение завершается неудачей.

Комментарии:

1. Это в значительной степени работает (я думаю). Мне пришлось изменить arrayForKey на objectForKey , так как у меня возникла ошибка: 'NSArray' is not a subtype of 'AnyObject[]' .

2. Круто, да, я не был уверен, было ли это специально. Swift Array <-> NSArray bridging, похоже, по-прежнему иногда возникают проблемы.

3. У меня это не работает… Я скопировал код прямо в свой проект, и он не будет работать