Я новичок в 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]];
}
@LoVo добавил тело метода





Проблема в том, что метод 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.
@AlessioCrestani, вы можете легко проверить это, изменив свой вызов getTutorialDone(forEmail:), чтобы специально передать значение nil, например if (RealmManager.sharedInstance()?.loggedUser()?.agreementPhotoRead.boolValue ?? false || PreferencesManager.getTutorialDone(forEmail: nil)){ }. Кстати, в вашем вопросе нет упоминания о методе continueToRecording ...
continueToRecording() - это метод с оператором if в качестве первой строки, извините, если я не упоминал об этом раньше.
@AlessioCrestani другой возможной ошибкой может быть не дополнительная цепочка agreementPhotoRead.boolValue, но я не могу сказать наверняка без дополнительного контекста.
Я попытался передать электронное письмо с нулевым значением на getTutorialDone, и, как я уже сказал ранее, это ошибка NSInvalidArgument, а не EXC_BREAKPOINT. Какой контекст вам нужен для дополнительных задач цепочки? Я могу написать все методы
Многие ошибки отображаются только как EXC_BAD_INSTRUCTION или EXC_BREAKPOINT, когда быстрое ожидание неверно и запускает только runtimetrap, а точка входа приложения не записывается в быстром. Вот некоторые из них: - принудительное разворачивание nil, -принужденная попытка выражения (попробуйте!), Вызывающая ошибку, - выход за пределы индексации в массивы, - сбои предварительных условий, - сбои утверждения, - вызовы fatalError
@AlessioCrestani какой тип agreementPhotoRead? Неужели это nil? Является ли это неявно развернутым необязательным в Swift?
'@property NSNumber <RLMBool> * agreementPhotoRead;' это свойство в Objective-C. Конечно, это может быть ноль
@AlessioCrestani, в этом случае вы также должны быть необязательной цепочкой вызова на boolValue :) RealmManager.sharedInstance()?.loggedUser()?.agreementPhotoRead?.boolValue
Может ли метод:
PreferencesManager.getTutorialDone(forEmail:)обрабатывать необязательное значение, которое также может быть нулевым?