SoFunction
Updated on 2025-03-02

Example of method to use optional values? and! in swift

Optional Optional Value

Optional is a major feature of Swift and is also the most confusing problem for beginners of Swift.

When defining a variable, if the variable is specified, it means that the variable can have a value of the specified type or it can be nil.

In addition, Swift's nil is also somewhat different from Objective-C. In Objective-C, only objects can be nil. In Swift, when the basic type (shaping, floating point, boolean, etc.) has no value, it is also nil, rather than an initial value. A value without an initial value cannot be used, which results in the Optional type. It is easy to define an Optional value, just add a question mark (?) to the type, such as:

var str: String?

The difference between an Optional value and a non-Optional value is that although the Optional value has not been initialized, although it is nil, ordinary variables do not even have nil:

// Not initialized, but is an Optional type, nilvar str: String?
str //Output nil// Not initialized, not Optional typevar str2: String
str2  //An error occurred while using

About optional values! and ? use

Let's take a look at a chestnut first

class House {
 //How many rooms are there in the house var numRooms:Int = 5
}

class Person {
 //A person may or may not have a house, so set the properties of the house as optional var house: House?
}

let xiaowang = Person()
//Xiaowang has no house at this time//If you try to call the house property of xiaowang, access the house's numRooms property.  The process is as follows://1. The first method: force unpack the house and use it!  .  But at this time the house has no value, so the result is directly crashing.let numroom = !.numRooms

//2. Use if letif let house =  {
 let roomCount = 
}

//3. Use ?if let numRooms = ?.numRooms {
 let numroom = numRooms
}

Now the problem is here

  1. How can I directly answer the question mark after the house? Isn't it possible for the compiler to know whether it has a value and will report an error if it is called after answering the question mark?
  2. Isn't the numRooms property of house a required property? Why is it used if let to make optional binding?

This involves a new knowledge called nullable chain call.

Can be called in an empty chain. It means that when calling an object's attribute or method, a question mark can be used directly. At this time, regardless of whether its attributes are optional. Finally, all return an optional value.

Can be called in an empty chain

Can be called in an empty chain. It refers to when an optional object's properties and methods are called. You can do not forcibly unpack the optional object first. Use directly? At this time, this feature can be selected, and it will be passed to the process of finally returning an optional value.

Also give the above examples.

if let numRooms = ?.numRooms {
 let numroom = numRooms
}

At this time, the numRooms property of the optional object house is called. Conditions met:

  • House is optional
  • Call the properties of the optional object house numRooms
  • At this time, there is no need to force unpack the optional object.
  • This feature is optional and passed to numRooms
  • So, return an optional value of numRooms.

Let me give you another chestnut

class Room {
 //The room has four windows var numWindows:Int = 4
}

class House {
 //How many rooms are there in the house var room: Room?
}

class Person {
 //A person may or may not have a house, so set the properties of the house as optional var house: House?
}

let windows = Person().house?.room?.numWindows

if let w = windows {
 //windows are optional values}
  1. Accessed an optional object property Room
  2. Then house does not need to be forced to unpack, and does not care whether the Room is optional before. At this time, the optional features are transmitted to the Room, and Room has also become optional.
  3. Then access the numWindows property of the optional object Room, and the optional feature is passed to numWindows.
  4. Returns an optional numWindows. At this time, windows is optional.

Let's talk about the method of calling optional objects

The principle of the adjustment method is the same.

Let’s talk about the method first. Any method in swift has a return value. There is no return value, it just says it returns Void. Void is also a return value.
If a method of the optional object is called. Then the optional feature of the optional object will be automatically passed to the return value of the method.

Take a chestnut:

class Room {
 //The room has four windows var numWindows:Int = 4

 func closeWindow() {
 print("Close the window")
 }
}

class House {
 //How many rooms are there in the house var room: Room?

 func closeDoor() {
 print("close the door")
 }
}

class Person {
 //A person may or may not have a house, so set the properties of the house as optional var house: House?
}

let person = Person()
//In the following sentence, the optional feature of house is passed to the return value of closeDoor() Void, so the actual return is an optional Void type?.closeDoor()

//So, if the method exists, you can determine whether it is nilif ?.closeDoor() != nil {
 //The method of closeDoor closed has been successfully called} 

if ?.room?.closeWindow() != nil {
 // CloseWindow method call successfully}

If you don't care whether the call is successful, then it is not necessary to determine whether it is nil or not.

Finally, let's make a summary

  • Can I use ? Number
  • When accessing the properties of an optional object, from ? All the latter are optional, and the returned value must be an optional value.
  • When accessing optional objects. Determine whether nil is to confirm whether the method is and the call is successful.

Look at the Ritsuko in the project

//Look at the calling properties firstclass PersonCell: UITableViewCell {

 var person: Person? {
 didSet {
  //Person is optional in these two places.  Use to access the person's properties?  , which returns an optional name  textLabel?.text = person?.name
  detailTextLabel?.text = person?.phone
 }
 }

 override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
 (style: .Subtitle, reuseIdentifier: reuseIdentifier)

 accessoryType = .DisclosureIndicator
 }

 required init?(coder aDecoder: NSCoder) {
 fatalError("init(coder:) has not been implemented")
 }
}

//Look at the adjustment method again func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
 let detailVC = DetailViewController()

  = persons[]
  = {
  ([indexPath], withRowAnimation: .Top)
 }

//Here, navigationController is an optional property, and the pushViewController method returns an optional Void.  navigationController?.pushViewController(detailVC, animated: true) }

 //If you want to determine whether the pushViewController is successful, you can do the following job if navigationController?.pushViewController(detailVC, animated: true) != nil {
 //Pushed successfully}

Summarize

The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.