Reputation: 37
This code is from Apple's new book. My question is: How come "let roomCount = john.residence?.numberOfRooms" is nil, I thought .numberOfRooms should be 1 but in xcode it says is nil I just don't get why is nil. If anyone can clarify me this that would be awesome. Thank you in advance.
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
let john = Person()
let roomCount = john.residence?.numberOfRooms
john.residence = Residence()
john.residence?.numberOfRooms
if let roomCount = john.residence?.numberOfRooms {
print("John's residence has \(roomCount) room(s).")
} else {
print("Unable to retrieve the number of rooms.")
}
Upvotes: 0
Views: 1411
Reputation: 1310
In the example, line let john = Person()
creates a object john of type Person.
Person type consist of optional property residence i.e. var residence: Residence?
Here residence is nil because Type Residence is not initialized yet. But one can access its property numberOfRooms even residence is nil (because here Optional Chaining is used) and result of accessing it, is nil
let roomCount = john.residence?.numberOfRooms
Afterward when residence is initialized and assigned,
john.residence = Residence()
Now, john.residence object is initialized and when accessing its numberOfRooms property, it returns default assigned value 1.
In swift, properties are accessible for optional types whether they are nil or not (initialized or not initialized).
Optional Chaining
Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil, the property, method, or subscript call returns nil. Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.
Upvotes: 2
Reputation: 2011
let roomCount = john.residence?.numberOfRooms
in this line the roomCount have to be nil because you didn't set the residence instance variable. roomCount is not nil when it comes after john.residence = Residance().
Okey so
let roomCount = john.residence?.numberOfRooms
is like this
let roomCount: Int! = nil
if let unwrappedResidence = john.residence
{
roomCount = unwrappedResidence.numberOfRooms
}
So If residence is nil, the roomCount is being nil.
Upvotes: 3
Reputation: 71852
residence
is not initialised yet when you are trying to use it with:
let roomCount = john.residence?.numberOfRooms
So this will always print nil
because residence
have nothing to return.
If you want to use .numberOfRooms
first initialise your residence
instance and use it this way:
let john = Person()
john.residence = Residence()
let roomCount = john.residence?.numberOfRooms // 1
One more way to do it is initialise it into your Person
class:
class Person {
var residence = Residence()
}
Now you can use .numberOfRooms
this way:
let john = Person()
let roomCount = john.residence.numberOfRooms // 1
Upvotes: 2