EXC_BREAKPOINT при необязательном связывании

Я новичок в Swift, но я опытный разработчик iOS на Objective-c. В настоящее время crashlytics сообщает о сбое EXC_BREAKPOINT одному пользователю, но это систематический сбой. Я пробовал с несколькими устройствами и версией ОС, но я не могу ее воспроизвести.

строка:

if (RealmManager.sharedInstance()?.loggedUser()?.agreementPhotoRead.boolValue ?? false || PreferencesManager.getTutorialDone(forEmail: RealmManager.sharedInstance()?.loggedUser()?.email)){
    }

Что не так с необязательной цепочкой? Версия Swift - 4.2.

Обновлено: geTutorialDone метод находится в объекте-c. Вот код:

+ (BOOL)getTutorialDoneForEmail:(NSString *)email
{
    return [[NSUserDefaults standardUserDefaults] boolForKey:[TUTORIAL_PREF stringByAppendingString:email]];
}

Может ли метод: PreferencesManager.getTutorialDone(forEmail:) обрабатывать необязательное значение, которое также может быть нулевым?

LoVo 29.11.2018 11:15

@LoVo добавил тело метода

Alessio Crestani 29.11.2018 11:17
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
136
1

Ответы 1

Проблема в том, что метод stringByAppendingString на самом деле не работает, если его входным аргументом NSString является nil, как описано в документация метода.

Raises an NSInvalidArgumentException if aString is nil.

Вы должны выполнить проверку nil перед вызовом метода в getTutorialDoneForEmail или, что еще лучше, сделать так, чтобы getTutorialDoneForEmail принимал только не-nilNSString.

+ (BOOL)getTutorialDoneForEmail:(nonnull NSString *)email {
    return [[NSUserDefaults standardUserDefaults] boolForKey:[TUTORIAL_PREF stringByAppendingString:email]];
}

Более того, если agreementPhotoRead может быть nil, вам необходимо связать его вызов с boolValue, иначе Swift обработает его как неявно развернутый необязательный, что приведет к ошибке времени выполнения в случае, если agreementPhotoRead на самом деле был nil.

RealmManager.sharedInstance()?.loggedUser()?.agreementPhotoRead?.boolValue

и почему Crashlytics сообщает о EXC_BREAKPOINT на continueToRecording, а не о NSInvalidArgumentException на getTutorialDone? Я также уверен, что пользователь, у которого возникла проблема, передает электронное письмо, а не значение nil.

Alessio Crestani 29.11.2018 11:29

@AlessioCrestani, вы можете легко проверить это, изменив свой вызов getTutorialDone(forEmail:), чтобы специально передать значение nil, например if (RealmManager.sharedInstance()?.loggedUser()?.agreementPho‌​toRead.boolValue ?? false || PreferencesManager.getTutorialDone(forEmail: nil)){ }. Кстати, в вашем вопросе нет упоминания о методе continueToRecording ...

Dávid Pásztor 29.11.2018 11:35
continueToRecording() - это метод с оператором if в качестве первой строки, извините, если я не упоминал об этом раньше.
Alessio Crestani 29.11.2018 11:36

@AlessioCrestani другой возможной ошибкой может быть не дополнительная цепочка agreementPhotoRead.boolValue, но я не могу сказать наверняка без дополнительного контекста.

Dávid Pásztor 29.11.2018 11:39

Я попытался передать электронное письмо с нулевым значением на getTutorialDone, и, как я уже сказал ранее, это ошибка NSInvalidArgument, а не EXC_BREAKPOINT. Какой контекст вам нужен для дополнительных задач цепочки? Я могу написать все методы

Alessio Crestani 29.11.2018 11:41

Многие ошибки отображаются только как EXC_BAD_INSTRUCTION или EXC_BREAKPOINT, когда быстрое ожидание неверно и запускает только runtimetrap, а точка входа приложения не записывается в быстром. Вот некоторые из них: - принудительное разворачивание nil, -принужденная попытка выражения (попробуйте!), Вызывающая ошибку, - выход за пределы индексации в массивы, - сбои предварительных условий, - сбои утверждения, - вызовы fatalError

LoVo 29.11.2018 11:44

@AlessioCrestani какой тип agreementPhotoRead? Неужели это nil? Является ли это неявно развернутым необязательным в Swift?

Dávid Pásztor 29.11.2018 11:46

'@property NSNumber <RLMBool> * agreementPhotoRead;' это свойство в Objective-C. Конечно, это может быть ноль

Alessio Crestani 29.11.2018 11:49

@AlessioCrestani, в этом случае вы также должны быть необязательной цепочкой вызова на boolValue :) RealmManager.sharedInstance()?.loggedUser()?.agreementPhotoR‌​ead?.boolValue

Dávid Pásztor 29.11.2018 11:51

Другие вопросы по теме