I've just finished debugging a situation where some of my labels were not displaying any text, despite the string in question definitely containing a value (it was printing the line before). I eventually pinned it down to returning different values depending on the way I accessed the string. Please note I'm not looking for ways to work around this, I am looking for a reason I am missing as to why this behaviour happens.
I had a protocol with the following optional String property, set to default to nil:
protocol SomeProtocol {
var titleString: String? { get }
}
extension SomeProtocol {
var titleString: String? {
return nil
}
}
Which was implemented in a class with a not optional String, with title set elsewhere:
class SomeClass: SomeProtocol {
var title: String
var titleString: String {
return title
}
}
When attempting to access the value of titleString from a SomeClass object, it always returned nil, regardless of the title property. This was seen through assigning to a label like:
label.text = someClassInstance.titleString
However, when I printed the value or set the label through
label.text = "\(someClassInstance.titleString)"
everything worked, and it displayed the text.
I've narrowed the source of this down to where I've overridden the optional property with one not optional. Clearly when I access the property directly it is returned by the protocol implementation, while using it by string interpolation returns the class one. What is actually behind this behaviour?
Edit: to demonstrate this behaviour run this gist in an Xcode playground: https://gist.github.com/CaileanWilkinson/357c17f36d04b522b9bcf1241a825d9f

nileither way.textproperty and then print the label'stextin your playgroundtextproperty allowed my to reproduce the issue.String?then thetitleStringwith the return type ofString?is called. If the result is known to be aStringthen thetitleStringwith the return type ofStringis called. I don't know if this is a bug in some way but it is enough info to avoid the problem.