Что означает" фатальная ошибка: неожиданно найденный ноль при развертывании необязательного значения"?



моя программа Swift рушится с EXC_BAD_INSTRUCTION и эта ошибка. Что это значит и как это исправить?




фатальная ошибка: неожиданно обнаружил нулю при разворачивании необязательное значение






этот пост предназначен для сбора ответов на" неожиданно найденные нулевые " вопросы, поэтому они не разбросаны и трудно найти. Не стесняйтесь добавлять свой собственный ответ или редактировать существующий ответ Вики.

699   8  

8 ответов:

ответ Вики. Если вы чувствуете, что это может быть сделано лучше, не стесняйтесь редактировать!

фон: что является необязательным?

В Swift, Optional это универсального типа это может содержать значение (любого вида), или вообще никакого значения.

во многих других языках программирования конкретное значение "sentinel" часто используется для указания отсутствие значения. В Objective-C, например, nil (the нулевой указатель) указывает на отсутствие объекта. Но это становится более сложным при работе с примитивными типами - должен -1 используется для указания отсутствия целого числа, или, возможно,INT_MIN, или какое-то другое целое число? Если какое-либо конкретное значение выбрано для обозначения "нет целого числа", это означает, что оно больше не может рассматриваться как действительный значение.

Swift является тип-безопасным язык, что означает, что язык помогает вам четко понимать типы значений, с которыми может работать ваш код. Если часть кода ожидает строку, тип безопасности предотвращает передачу его Int по ошибке.

В Swift, любого типа можно сделать дополнительно. Необязательное значение может принимать любое значение из исходного типа,или специальное значение nil.

опции определяются с ? суффикс по типу:

var anInt: Int = 42
var anOptionalInt: Int? = 42
var anotherOptionalInt: Int?    // `nil` is the default when no value is provided

отсутствие значения в необязательном показывается nil:

anOptionalInt = nil

(обратите внимание, что это nil - это не то же самое как nil в Objective-C. В Objective-C,nil это отсутствие действительного объект указателя; в Swift, Optionals не ограничены объектами / ссылочными типами. Необязательно ведет себя так же, Хаскелл может быть.)


почему я получаю "фатальная ошибка: неожиданно обнаружил нулю при разворачивании необязательное значение"?

чтобы получить доступ к необязательному значению (если оно вообще есть), вам нужно развернуть его. Необязательное значение может быть развернуто безопасно или принудительно. Если вы заставляете-разверните необязательный, и он не иметь значение, ваша программа рухнет с выше сообщение.

Xcode покажет вам сбой, выделив строку кода. Проблема возникает на этой линии.

crashed line

эта авария может произойти с двумя различными видами force-unwrap:

1. Явная Сила Разворачивания

это делается с помощью ! оператор на факультативной. Например:

let anOptionalString: String?
print(anOptionalString!) // <- CRASH

как anOptionalString и nil здесь вы получите сбой на линии где вы заставляете развернуть его.

2. Неявно Развернутые Опции

они определяются с !, а не ? после типа.

var optionalDouble: Double!   // this value is implicitly unwrapped wherever it's used

предполагается, что эти параметры содержат значение. Поэтому всякий раз, когда вы обращаетесь к неявно развернутой опции, она автоматически будет принудительно развернута для вас. Если он не содержит значения, произойдет сбой.

print(optionalDouble) // <- CRASH

для того, чтобы выяснить, какая переменная вызвала авария, вы можете держать при нажатии, чтобы показать определение, где вы можете найти дополнительный тип.

IBOutlets, в частности, обычно неявно развернуты optionals. Это потому, что ваш xib или раскадровка свяжет розетки во время выполнения,после инициализации. Поэтому вы должны убедиться, что вы не получаете доступ к розеткам до их загрузки. Вы также должны проверить, что соединения исправьте в вашем файле раскадровки / xib, иначе значения будут nil во время выполнения, и поэтому сбой, когда они неявно развернуты.


когда я должен когда-нибудь заставить развернуть дополнительный?

Явная Сила Разворачивала

как правило, вы никогда не должны явно принудительно разворачивать необязательный элемент с помощью ! оператора. Там могут быть случаи, когда с помощью ! приемлемо – но вы должны только когда-либо использовать его, если вы 100% уверен, что опция содержит значение.

Хотя нет мая быть случай, когда вы можете использовать силу разворачивания, как вы знаете, для факт что необязательный содержит значение-нет один место, где вы не можете безопасно развернуть, что необязательно вместо этого.

Неявно Развернутые Опции

эти переменные разработаны так, что вы можете отложить назначение, пока в коде. Это код ответственность, чтобы убедиться, что они имеют значение, прежде чем открыть их. Однако, поскольку они включают в себя принудительное разворачивание, они по – прежнему небезопасны-поскольку они предположим ваше значение не равно nil, даже если присвоение nil является допустимым.

вы должны использовать только неявно развернутые опциональные значения как в крайнем случае. Если вы можете использовать ленивый переменной, или обеспечить значение по умолчанию для переменной, вы должны сделать, вместо того, чтобы использовать неявно развернул необязательно.

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

как я могу безопасно иметь дело с Варианты?

самый простой способ проверить, содержит ли необязательное значение, - это сравнить его с nil.

if anOptionalInt != nil {
    print("Contains a value!")
} else {
    print("Doesn’t contain a value.")
}

тем не менее, 99,9% времени при работе с optionals, вы на самом деле хотите получить доступ к значению, которое он содержит, если он содержит один вообще. Для этого вы можете использовать Факультативного Связывания.

Факультативного Связывания

необязательная привязка позволяет проверить, содержит ли необязательное значение-и позволяет чтобы присвоить развернутое значение новой переменной или константе. Он использует синтаксис if let x = anOptional {...} или if var x = anOptional {...}, в зависимости от того, нужно ли изменить значение новой переменной после ее привязки.

например:

if let number = anOptionalInt {
    print("Contains a value! It is \(number)!")
} else {
    print("Doesn’t contain a number")
}

что это делает, это сначала проверить, что необязательный содержит значение. Если это тут, затем значение 'unwrapped' присваивается новой переменной (number)-который вы можете свободно использовать, как если бы он был необязательным. Если необязательный не содержат значение, то предложение else будет вызвано, как и следовало ожидать.

что аккуратно О дополнительной привязки, вы можете развернуть несколько optionals в то же время. Вы можете просто отделить операторы с запятой. Заявление будет успешным, если все опционные были развернуты.

var anOptionalInt : Int?
var anOptionalString : String?

if let number = anOptionalInt, let text = anOptionalString {
    print("anOptionalInt contains a value: \(number). And so does anOptionalString, it’s: \(text)")
} else {
    print("One or more of the optionals don’t contain a value")
}

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

if let number = anOptionalInt, number > 0 {
    print("anOptionalInt contains a value: \(number), and it’s greater than zero!")
}

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

A заявление охранника позволяет определить условие успеха – и текущая область будет продолжать выполняться только в том случае, если это условие встретились. Они определяются с помощью синтаксиса guard condition else {...}.

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

guard let number = anOptionalInt else {
    return
}

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

если anOptionalInt содержит значение, оно будет развернуто и присвоено новому number константы. Код после затем охранник продолжит выполнение. Если он не содержит значения-охранник выполнит код в скобках, что приведет к передаче управления, так что код сразу после этого не будет выполнен.

реальная аккуратная вещь о операторах guard-это развернутое значение, которое теперь доступно для использования в коде, который следует за оператором (поскольку мы знаем, что будущий код может только выполнить, если опция имеет значение). Это отлично подходит для устранения ‘дум’ создается путем вложения нескольких операторов if.

например:

guard let number = anOptionalInt else {
    return
}

print("anOptionalInt contains a value, and it’s: \(number)!")

Guards также поддерживает те же аккуратные трюки, что и оператор if, например, разворачивание нескольких опциональных функций одновременно и использование where предложения.

использование оператора if или guard полностью зависит от того, будет ли какой-либо будущий код требует опционное для того чтобы содержать a значение.

Оператор Слияния Nil

The Оператор Слияния Nil это изящная сокращенная версия тернарный условный оператор, в первую очередь, предназначены для преобразования обязательны не обязательны. Он имеет синтаксис a ?? b, где a является необязательным типом и b это тот же тип, что и a (хотя, как правило, не обязательно).

это по существу позволяет вам сказать " если a содержит значение, разверните его. Если он не возвращается b вместо". Например, вы можете использовать его следующим образом:

let number = anOptionalInt ?? 0

это будет определять a number постоянная Int тип, который будет либо содержать значение anOptionalInt, если он содержит значение, или 0 в противном случае.

это просто сокращение для:

let number = anOptionalInt != nil ? anOptionalInt! : 0

Дополнительные Цепочки

можно использовать Дополнительные Цепочки для вызова метода или обращения к свойству по необязательный. Это просто делается путем суффикса имени переменной с ? при его использовании.

например, скажем, у нас есть переменная foo типа необязательного Foo экземпляра.

var foo : Foo?

если бы мы хотели вызвать метод на foo это ничего не возвращает, мы можем просто сделать:

foo?.doSomethingInteresting()

если foo содержит значение, этот метод будет вызван на нем. Если этого не произойдет, ничего плохого не произойдет-код просто продолжит работу проведение.

(это похоже на отправку сообщений в nil в Objective-С)

это также может быть использовано для установки свойств, а также методов вызова. Например:

foo?.bar = Bar()

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

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

(это потому, что необязательное значение будет возвращать Void?, а не Void на метод, который ничего не возвращает)

например:

if (foo?.bar = Bar()) != nil {
    print("bar was set successfully")
} else {
    print("bar wasn’t set successfully")
}

однако все становится немного сложнее при попытке получить доступ к свойствам или вызвать методы, которые возвращают значение. Потому что foo не является обязательным, все, что возвращается из него также будет необязательный. Чтобы справиться с этим, вы можете либо развернуть optionals, которые возвращаются с помощью одного из приведенных выше методов – или развернуть foo сам перед доступом к методам или вызовом методов, возвращающих значения.

кроме того, как следует из названия, вы можете "связывать" эти утверждения вместе. Это означает, что если foo имеет необязательное свойство baz, который имеет свойство qux – вы могли бы написать следующее:

let optionalQux = foo?.baz?.qux

опять же, потому что foo и baz являются необязательными, значение, возвращаемое из qux всегда будет необязательным, независимо от того,qux сам по себе не является обязательным.

map и flatMap

часто недоиспользуемая функция с optionals-это возможность использовать map и flatMap функции. Они позволяют применять необязательные преобразования к необязательным переменным. Если необязательный параметр имеет значение, к нему можно применить данное преобразование. Если он не имеет значения, он останется nil.

например, допустим, у вас есть необязательная строка:

let anOptionalString:String?

с применением , если anOptionalString не имеет значения map вернутся nil. Например:

var anOptionalString:String?

anOptionalString = anOptionalString.map {unwrappedString in
    return "foo".stringByAppendingString(unwrappedString)
}

print(anOptionalString) // nil

flatMap работает аналогично map, за исключением того, что он позволяет вам вернуться другое опционный изнутри тела закрытия. Это означает, что вы можете ввести необязательный параметр в процесс, который требует необязательного ввода, но может выводить сам необязательный параметр.

try!

обработка ошибок Swift систему можно безопасно использовать с Do-Try-Catch:

do {
    let result = try someThrowingFunc() 
} catch {
    print(error)
}

если someThrowingFunc() выдает ошибку, ошибка будет благополучно поймана в catch блок.

The error константа, которую вы видите в catch блок не был объявлен нами-он автоматически генерируется catch.

вы также можете объявить error yourself, оно имеет преимущество мочь бросить его к полезному формату, ибо пример:

do {
    let result = try someThrowingFunc()    
} catch let error as NSError {
    print(error.debugDescription)
}

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

там же try?, который поглощает ошибка:

if let result = try? someThrowingFunc() {
    // cool
} else {
    // handle the failure, but there's no error information available
}

но система обработки ошибок Swift также обеспечивает способ "принудительной попытки" с try!:

let result = try! someThrowingFunc()

концепции, описанные в этом посте, также применяются здесь: Если возникает ошибка, приложение будет крушение.

вы должны только когда-либо использовать try! если вы можете доказать, что его результат никогда не подведет в вашем контексте - а это очень редко.

большую часть времени вы будете использовать полную систему Do-Try-Catch - и дополнительный, try?, в редких случаях, когда обработка ошибки-это не важно.


ресурсы

TL; DR ответ

С очень редкими исключениями, это правило золотое:

избегайте использования !

объявить переменную необязательно (?), неявно развернутые опциональные (IUO) (!)

другими словами, лучше использовать:
var nameOfDaughter: String?

вместо:
var nameOfDaughter: String!

развернуть необязательную переменную с помощью if let или guard let

либо развернуть переменную, как это:

if let nameOfDaughter = nameOfDaughter {
    print("My daughters name is: \(nameOfDaughter)")
}

или такой:

guard let nameOfDaughter = nameOfDaughter else { return }
print("My daughters name is: \(nameOfDaughter)")

этот ответ должен был быть кратким,для полного понимания прочитать принятый ответ

этот вопрос поднимается ВСЕ ВРЕМЯ так. Это одна из первых вещей, с которыми борются новые разработчики Swift.

Справочная информация:

Swift использует понятие "Optionals" для работы со значениями, которые могут содержать значение, или нет. В других языках, таких как C, вы можете хранить значение 0 в переменной, чтобы указать, что оно не содержит значения. Однако, что если 0 является допустимым значением? Затем вы можете использовать -1. Что делать, если -1 является допустимым значением? И на.

Swift optionals позволяет настроить переменную любого типа, чтобы содержать либо допустимое значение, либо нет значения.

вы ставите знак вопроса после типа, когда вы объявляете переменную в mean (тип x или без значения).

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

дополнительный должен быть "развернут", чтобы извлечь значение внутри.

The"!"оператор - это" сила разворачивания" оператор. Он говорит: "Поверь мне. Я знаю, что делаю. Я гарантирую, что при запуске этого кода переменная не будет содержать nil.- Если ты ошибаешься,то разобьешься.

если вы действительно do знайте, что вы делаете, избегайте "!"принудительно разверните оператора. Это, вероятно, самый большой источник сбоев для начинающих программистов Swift.

Как бороться с опциями:

есть много других способов борьбы с опциями, которые являются более безопасными. Вот некоторые (не исчерпывающий список)

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

вот пример необязательной привязки с нашим foo дополнительно:

if let newFoo = foo //If let is called optional binding. {
  print("foo is not nil")
} else {
  print("foo is nil")
}

обратите внимание, что переменная, которую вы определяете при использовании необязательной привязки, существует только (только "в области видимости") в теле if заявление.

кроме того, вы можете использовать оператор guard, который позволяет вам выйти из функции, если переменная равна nil:

func aFunc(foo: Int?) {
  guard let newFoo = input else { return }
  //For the rest of the function newFoo is a non-optional var
}

охранные заявления были добавлены в Swift 2. Guard позволяет сохранить " золотой путь "через ваш код и избежать постоянно растущих уровней вложенных ifs, которые иногда возникают в результате использования необязательной привязки" if let".

существует также конструкция, называемая "нулевым коалесцирующим оператором". Он принимает форму " optional_var ?? replacement_val". Он возвращает необязательную переменную с тем же типом, что и данные, содержащиеся в необязательном. Если необязательный параметр содержит nil, он возвращает значение выражения после "??" символ.

таким образом, вы можете использовать такой код:

let newFoo = foo ?? "nil" // "??" is the nil coalescing operator
print("foo = \(newFoo)")

вы также можете использовать обработку ошибок try/catch или guard, но, как правило, один из других методов выше чище.

EDIT:

еще один, чуть более тонкий gotcha с optionals является "неявно развернутые опции. Когда мы объявляем foo, мы могли бы сказать:

var foo: String!

в этом случае foo по-прежнему является необязательным, но вам не нужно разворачивать его, чтобы ссылаться на него. Это означает, что каждый раз, когда вы пытаетесь ссылаться на foo, вы разбиваетесь, если это ноль.

так этот код:

var foo: String!


let upperFoo = foo.capitalizedString

произойдет сбой при ссылке на свойство foo capitalizedString, даже если мы не будем принудительно разворачивать foo. отпечаток выглядит нормально, но это не так.

таким образом, вы хотите быть действительно осторожнее с неявно развернутые опции. (и, возможно, даже избежать их полностью, пока у вас есть твердое понимание обязательны.)

итог: Когда вы впервые изучаете Swift, притворитесь "!- характер не является частью языка. Это может навлечь на тебя неприятности.

во-первых, вы должны знать, что необязательное значение. Вы можете перейти к Запуск Быстрого Программирования

за деталь.

во-вторых, вы должны знать дополнительное значение имеет два статуса. Один-это полное значение, а другой-нулевое значение. Поэтому, прежде чем реализовать необязательное значение, вы должны проверить, в каком состоянии оно находится.

можно использовать if let ... или guard let ... else и так далее.

другой способ, если вы не хотите, чтобы проверить его состояние перед вашим реализовать, вы также можете использовать var buildingName = buildingName ?? "buildingName" вместо.

поскольку приведенные выше ответы четко объясняют, как безопасно играть с опционными. Я постараюсь объяснить, какие опционные действительно в swift.

другой способ объявить необязательную переменную -

var i : Optional<Int>

и необязательный тип-это не что иное, как перечисление с двумя случаями, т. е.

 enum Optional<Wrapped> : ExpressibleByNilLiteral {
    case none 
    case some(Wrapped)
    .
    .
    .
}

Итак, чтобы присвоить ноль нашей переменной 'i'. Мы можем сделать var i = Optional<Int>.none или чтобы присвоить значение, мы передадим некоторое значение var i = Optional<Int>.some(28)

согласно swift, ' nil ' - это отсутствие ценности. И создать экземпляр, инициализированный с помощью nil мы должны соответствовать протоколу под названием ExpressibleByNilLiteral и здорово, если вы догадались, только Optionals соответствуют ExpressibleByNilLiteral и соответствие другим типам не рекомендуется.

ExpressibleByNilLiteral имеет один метод под названием init(nilLiteral:) который инициализирует instace с нулем. Обычно вы не вызываете этот метод, и в соответствии с документацией swift не рекомендуется вызывать этот инициализатор непосредственно как компилятор вызывает его всякий раз, когда вы инициализируете необязательный тип с помощью nil литерал.

даже я должен обернуть (Не каламбур) мою голову вокруг Optionals :D Счастливый Swfting Все.

у меня была эта ошибка один раз, когда я пытался установить мои значения выходов из метода prepare for segue следующим образом:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? DestinationVC{

        if let item = sender as? DataItem{
            // This line pops up the error
            destination.nameLabel.text = item.name
        }
    }
}

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

поэтому я решил это так:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? DestinationVC{

        if let item = sender as? DataItem{
            // Created this method in the destination Controller to update its outlets after it's being initialized and loaded
            destination.updateView(itemData:  item)
        }
    }
}

Контроллер Назначение:

// This variable to hold the data received to update the Label text after the VIEW DID LOAD
var name = ""

// Outlets
@IBOutlet weak var nameLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    nameLabel.text = name
}

func updateView(itemDate: ObjectModel) {
    name = itemDate.name
}

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

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

есть несколько сценариев, которые приводят к такого рода фатальная ошибка:

  1. заставили разворачивает:

    let user = someVariable!
    

    если someVariable это ноль, то вы получите аварию. Выполнив принудительное разворачивание, вы переместили ответственность за проверку nil от компилятора к вам, в основном, выполняя принудительное разворачивание, вы гарантируете компилятору, что у вас никогда не будет нулевых значений. И угадайте, что произойдет, если это произойдет?

    решение? Используйте дополнительные привязки (он же если-пусть), сделать переменную обработка есть:

    if user = someVariable {
        // do your stuff
    }
    
  2. принудительное рубрики:

    let myRectangle = someShape as! Rectangle
    

    здесь путем принудительного кастинга вы говорите компилятору больше не беспокоиться, так как у вас всегда будет Rectangle есть экземпляр. И пока это держится, у вас нет волноваться. Проблемы начинаются, когда вы или ваши коллеги из проекта начинают распространять значения, отличные от прямоугольника.

    решение? Используйте дополнительные привязки (он же если-пусть), сделать переменную обработка есть:

    if let myRectangle = someShape as? Rectangle {
        // yay, I have a rectangle
    }
    
  3. неявно развернутые опции. Предположим, у вас есть следующее определение класса:

    class User {
        var name: String!
    
        init() {
            name = "none yet"
        }
    
        func nicerName() {
            return "Mr/Ms " + name
        }
    }
    

    теперь, если никто не испортит name свойство, установив его в nil, тогда он работает, как ожидалось, однако, если User инициализируется из JSON, в котором отсутствует name ключ, то вы получите фатальную ошибку при попытке использовать свойство.

    решение? Не используйте их :) если вы не уверены на 102%, что свойство всегда будет иметь ненулевое значение к моменту его использования. Однако в большинстве случаев преобразование его в необязательный или необязательный будет работать. Создание этого необязательного также приведет к тому, что компилятор поможет вам, сообщив пути кода, которые вы пропустили, давая значение этому собственность

  4. неподключенные розетки. Это частный случай сценария №3. В основном у вас есть какой-то XIB-загруженный класс, который вы хотите использовать.

    class SignInViewController: UIViewController {
    
        @IBOutlet var emailTextField: UITextField!
    }
    

    теперь, если вы пропустили подключение розетки из редактора XIB, то приложение рухнет, как только вы захотите использовать розетку. Решение? Убедитесь, что все розетки подключены. Или используйте ? оператор на них: emailTextField?.text = "[email protected]". Или объявите выход как необязательный, хотя в этом случае компилятор будет заставить вас развернуть его по всему коду.

  5. значения, поступающие из Objective-C, и которые не имеют аннотаций nullability. Предположим, что у нас есть следующий класс Objective-C:

    @interface User: NSObject
    @property NSString *name;
    @end
    

    теперь, если аннотации nullability не указаны (явно или через NS_ASSUME_NONNULL_BEGIN/NS_ASSUME_NONNULL_END), то name свойство будет импортировано в Swift как String! (IUO - неявно развернутый необязательный). Как только какой-то swift код захочет использовать значение, он рухнет, в нулевых случаях.

    решение? Добавить аннотации возможность, чтобы ваша цель-C код. Однако будьте осторожны, компилятор Objective-C немного допускает, когда дело доходит до nullability, вы можете получить нулевые значения, даже если вы явно отметили их как nonnull.

фатальная ошибка: неожиданно обнаружил нулю при разворачивании необязательное значение

Он говорит, что вы используете переменную, значение которой не инициализировано или не установлено nil.

например

var tempVar: String?
print(tempVar!)

tempVar не инициализируется так приложение падает в этом случае, так что вы должны использовать

print(tempVar ?? "") 

пожалуйста, обратитесь к Дополнительные Цепочки для получения более подробной информации

Comments

    Ничего не найдено.