Let's say I have a class, and when I set its property, I want it to append that property with a file type like .fileType
:
class File {
var fileName: String {
get {
return self.fileName
}
set {
self.fileName = fileName + ".fileType"
}
}
}
Which I try to use like this:
let newFile = File()
newFile.fileName = "My File"
Unfortunately, the variable never sets:
I have two possible workarounds.
class File {
var fileName: String = "" {
didSet {
self.fileName += ".fileType"
}
}
}
let file = File()
file.fileName = "SomeName" // SomeName.fileType
But with this, I must wait until the value is already set before I can modify it. For this particular example, it doesn't make too much difference; however, I'd like to be able to avoid this.
This solution is based on the example here. Search for 'speedLimitedCar'
class File {
var fileName = ""
}
class SubFile: File {
override var fileName: String {
get {
return super.fileName
}
set {
super.fileName = newValue + ".fileType"
}
}
}
let subfile = SubFile()
subfile.fileName = "Hello" // Hello.fileType
I could also just create a secondary property to store the value and access that in the fileName's getter/setter, but is there a way to avoid all that and modify a property directly within its getter / setter?
If you use set
and get
then the property must be computed. There is no actual storage for it.
This code defines a var
to hold the data and a computed var
to handle the access. This is similar to what you had in Objective-C (except that in Objective-C you could "hide" the actual variable by making it private or, more recently, having it synthesized an never mentioned in the header).
class File {
// this stores the actual data, do not access it directly, consider it private
var theFileName: String = ""
// this is the real interface
var fileName: String {
get {
return self.theFileName
}
set(name) {
self.theFileName = name + ".fileType"
}
}
}
You can also write the set
like this:
set {
self.theFileName = newValue + ".fileType"
}
where newValue
is the default name if you omit the argument declaration for set
.
But what you probably want to do is what you already did (and rejected for unknown reasons):
var fileName: String = "" {
didSet {
self.fileName += ".fileType"
}
}
This is the correct way.
Note that "I must wait until the value is already set before I can modify it." is not true. It looks like that, but the compiler can very well optimize the code (and probably will).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With