Просмотры сборщика в Swift

#ios #swift #uipickerview

#iOS #swift #uipickerview

Вопрос:

Я столкнулся с проблемой с моим приложением в режиме выбора в didSelectRow функции

В некоторых ситуациях представление сборщика может быть нулевым, поэтому все инструкции внутри didSelectRow не будут считывать значение, и приложение вылетит.

Я много раз пробовал использовать разные решения, чтобы предотвратить этот сбой, но он не работает:

 func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)  {
        if (self.MEDARRAY[row].value(forKey: "medNumDay") as? NSInteger) != nil {

        let NumDay = self.MEDARRAY[row].value(forKey: "medNumDay") as? NSInteger
        let NumMed = self.MEDARRAY[row].value(forKey: "medNum") as? NSInteger
        Counter = (self.MEDARRAY[row].value(forKey: "takenCounter") as? NSInteger)!
        theTimeSet = (self.MEDARRAY[row].value(forKey: "nextTime")as? Date)!
        numberforday = (24 / NumDay!)
        thegetting.timeStyle = DateFormatter.Style.short
        TotalDose.text = String(NumDay! * NumMed!)
        RemainDose.text = String(Int(TotalDose.text!)! - Counter!)
        NextTimes.text = thegetting.string(from: theTimeSet!)
        }
        else{
                TotalDose.text = "No"
                RemainDose.text = "No"
                NextTimes.text = "No"            
        }
}
  

Еще одна попытка

 func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)  {
        if (MEDARRAY.count < 1) {
    let NumDay = self.MEDARRAY[row].value(forKey: "medNumDay") as? NSInteger
    let NumMed = self.MEDARRAY[row].value(forKey: "medNum") as? NSInteger
    Counter = (self.MEDARRAY[row].value(forKey: "takenCounter") as? NSInteger)!
    theTimeSet = (self.MEDARRAY[row].value(forKey: "nextTime")as? Date)!
    numberforday = (24 / NumDay!)
    thegetting.timeStyle = DateFormatter.Style.short
    TotalDose.text = String(NumDay! * NumMed!)
    RemainDose.text = String(Int(TotalDose.text!)! - Counter!)
    NextTimes.text = thegetting.string(from: theTimeSet!)
    }
    else{
            TotalDose.text = "No"
            RemainDose.text = "No"
            NextTimes.text = "No"            
    }
}
  

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

 let NumDay = self.MEDARRAY[row].value(forKey: "medNumDay") as? NSInteger
let NumMed = self.MEDARRAY[row].value(forKey: "medNum") as? NSInteger
Counter = (self.MEDARRAY[row].value(forKey: "takenCounter") as? NSInteger)!
theTimeSet = (self.MEDARRAY[row].value(forKey: "nextTime")as? Date)!
  

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

1. Дружеский совет: прекратите использовать код, подобный Objective-C, при написании Swift. Не используйте .value(forKey:) , используйте нижний индекс — не используйте NSInteger, но Int — не используйте как необязательный, чтобы позже принудительно развернуть, используйте необязательную привязку — избегайте использования NSArray / NSDictionary, используйте Swift Array / Dictionary и т. Д.

Ответ №1:

Если элементы, которые вы хотите идентифицировать, являются дополнительными, но для выполнения функции вам нужно, чтобы они имели ненулевые значения, поместите в начало функции оператор guard, который проверяет, доступно ли каждое значение:

 func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    guard row < MEDARRAY.count,
          MEDARRAY.count < 1,
          let NumDay : NSInteger = self.MEDARRAY[row].value(forKey: "medNumDay") as NSInteger,
          let NumMed = self.MEDARRAY[row].value(forKey: "medNum") as NSInteger,
          let Counter = (self.MEDARRAY[row].value(forKey: "takenCounter") as NSInteger
          let theTimeSet = (self.MEDARRAY[row].value(forKey: "nextTime") as Date else { print("Could not obtain all required values") ; return }

     // ... function continues here...
  

Обратите внимание, что вы можете связать оператор guard с запятыми, а также что эти константы не являются необязательными: если доступно значение, отличное от нуля, они будут инициализированы как необязательные, в противном случае будет запущено исключение guard. (Обратите внимание также на исправление вашего теста массива и ввода строки.)

Таким образом, если вы не можете инициализировать эти константы в ненулевые значения, функция просто завершит работу, что должно предотвратить сбой приложения. Конечно, это не объясняет, почему значения равны нулю, но, по крайней мере, поддерживает выполнение.

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

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

1. что я должен поместить после -> какой тип значения должен быть возвращен

2. @ammari — извиняюсь, это запутало проблему. Функция является стандартной функцией UIPicker и возвращает void , поэтому предложение guard может завершаться простым вызовом return . Я исправил свой ответ, чтобы убрать стрелку.

3. Поставьте тест на количество элементов в MEDARRAY первым в списке, а также введите проверку, что строка также равна 0 — если в MEDARRAY есть только одна запись, и вы ищете индекс> 0, произойдет сбой. Если все еще есть ошибка, не могли бы вы сообщить мне, какой вывод выводится на консоль?

4. я просто вставляю один itme в список, а остальная часть функции не запускается

5. Если в списке есть только один элемент, ваш тест должен быть MEDARRAY.count <2