#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