Home>

optional

Optional is a major feature of swift.It is also the most confusing problem for swift beginners.

When defining variables,If specifying this variable is optional,Indicates that the variable can have a value of a specified type,Can also be nil.

In addition, Swift's nil is also slightly different from objective-c.In objective-c, only objects can be nil, and in swift, when the underlying type (integer, floating point, Boolean, etc.) has no value,Is also nil, not an initial value,Value without initial value,Cannot be used,This produces an optional type. It's easy to define an optional value,Just add a question mark (?) after the type, such as:

var str:string?

The difference between an optional value and a non-optional value is that although the optional value is nil without initialization, ordinary variables do not even have nil:

//Not initialized,But is an optional type, nil
var str:string?
str //output nil
//Not initialized,Nor is it optional
var str2:string
str2 //Error while using

About optional values! with ?use

First look at a chestnut

class house {
 //house has several rooms
 var numrooms:int=5
}
class person {
 //A person may or may not have a house,So make the property of the house optional
 var house:house?
}
let xiaowang=person ()
//At this time xiaowang has no house
//If you try to call xiaowang's house property, access the house's numrooms property. The process is as follows:
//1. The first way:unpack the house forcibly,use ! . But house has no value at this time, so the result is a direct crash.
let numroom=xiaowang.house! .numrooms
//2. Use if let
if let house=xiaowang.house {
 let roomcount=house.numrooms
}
//3. Use?
if let numrooms=xiaowang.house?.numrooms {
 let numroom=numrooms
}

Here comes the problem

How can I directly answer the question mark behind house?Doesn't the compiler know if it has a value, it will report an error? Isn't the house's numrooms attribute a required attribute?Why use if let for optional binding?

This involves a new knowledge,Called nullable chain call.

Can be null-chained.Is when calling a property or method of an optional object,You can use the question mark directly,At this point, regardless of whether its attributes are optional.They all return an optional value.

Nullable chaining

Can be null-chained.This is when the properties and methods of an optional object are called.You can unforce the optional object first.Use directly?This feature is optional at this time,All the way down to the last property and method to call,The procedure that returns an optional value at the end.

Give the example above.

if let numrooms=xiaowang.house?.numrooms {
 let numroom=numrooms
}

At this point, the numrooms property of the optional object house is called. To meet the conditions:

house is an optional object Call the property numrooms of the optional object house Do not force unpack the optional object house at this time Optional this feature,Passed to numrooms So, return an optional value for numrooms.

Give another chestnut

class room {
 //The room has four windows
 var numwindows:int=4
}
class house {
 //house has several rooms
 var room:room?
}
class person {
 //A person may or may not have a house,So make the property of the house optional
 var house:house?
}
let windows=person (). house?.room&.63 #.numwindows
if let w=windows {
 //windows is optional
}
Access to the property room of an optional object house Then house does n’t have to unpack it forcibly,It doesn't matter if the room is optional before,At this time, the optional features are passed to the room, and the room also becomes optional. Then access the numwindows property of the optional object room. At this time, the optional feature is passed to numwindows. Returns an optional numwindows. Windows is optional at this time.

Let's talk about calling methods of optional objects

The principle of the tuning method is the same.

Let's talk about methods first.Any method in Swift has a return value.No return value,It just says that it returns void. void is also a return value.

If a method of an optional object is called.The optional characteristics of the optional object are automatically passed to the method's return value.

Give a chestnut:

class room {
 //The room has four windows
 var numwindows:int=4
 func closewindow () {
 print ("Close the window")
 }
}
class house {
 //house has several rooms
 var room:room?
 func closedoor () {
 print ("Close the door")
 }
}
class person {
 //A person may or may not have a house,So make the property of the house optional
 var house:house?
}
let person=person ()
//The following sentence,optional features of house,The return value void of closedoor () is passed, so it actually returns an optional void type
person.house?.closedoor ()
//So, determine if the method exists,Can determine whether it is nil
if person.house?.closedoor ()!=nil {
 //closedoor method closed successfully
}
if person.house?.room?.closewindow ()!=nil {
 //closewindow The method of closing the window is successful
}

If you don't care if the call succeeds,Then it is not necessary to judge whether it is nil

To conclude

When accessing properties or methods of optional objects,Can use ?number When accessing the properties of an optional object,From ?Become optional laterWhat is returned must be an optional value. When accessing methods of optional objects.Determine if it is nil to confirm whether the method is called successfully.

Look at the chestnuts in the project

//Look at the calling properties first
class personcell:uitableviewcell {
 var person:person?{
 didset {
  //These two places, person is optional.
To access the attributes of a person?, Which returns an optional name
  textlabel?.text=person?.name
  detailtextlabel?.text=person?.phone
 }
 }
 override init (style:uitableviewcellstyle, reuseidentifier:string?) {
 super.init (style:.subtitle, reuseidentifier:reuseidentifier)
 accessorytype=.disclosureindicator
 }
 required init?(coder adecoder:nscoder) {
 fatalerror ("init (coder :) has not been implemented")
 }
}
//Look at the tuning method again
 func tableview (tableview:uitableview, didselectrowatindexpath indexpath:nsindexpath) {
 let detailvc=detailviewcontroller ()
 detailvc.person=persons [indexpath.row]
 detailvc.finishedcallback={
  self.tableview.reloadrowsatindexpaths ([indexpath], withrowanimation:.top)
 }
//Here, navigationcontroller is an optional attribute,The pushviewcontroller method returns an optional void. navigationcontroller?.pushviewcontroller (detailvc, animated:true)
 }
 //To determine if the pushviewcontroller is successful,Can do the following
 if navigationcontroller?.pushviewcontroller (detailvc, animated:true)!=nil {
 //The push was successful
}

to sum up

  • Previous Java Swing component drop-down menu control JComboBox usage example
  • Next Java Swing component radio button JRadioButton usage example