Getter computed property vs. variable that returns a value - swift

Is there a difference between a getter computed property and variable that returns a value? E.g. is there a difference between the following two variables?
var NUMBER_OF_ELEMENTS1: Int {
return sampleArray.count
}
var NUMBER_OF_ELEMENTS2: Int {
get {
return sampleArray.count
}
}

A computer property with getter and setter has this form:
var computedProperty: Int {
get {
return something // Implementation can be something more complicated than this
}
set {
something = newValue // Implementation can be something more complicated than this
}
}
In some cases a setter is not needed, so the computed property is declared as:
var computedProperty: Int {
get {
return something // Implementation can be something more complicated than this
}
}
Note that a computed property must always have a getter - so it's not possible to declare one with a setter only.
Since it frequently happens that computed properties have a getter only, Swift let us simplify their implementation by omitting the get block, making the code simpler to write and easier to read:
var computedProperty: Int {
return something // Implementation can be something more complicated than this
}
Semantically there's no difference between the 2 versions, so whichever you use, the result is the same.

They are identical since both define a read-only computed property. But the former is preferable because it is shorter and more readable than the latter.

Related

Setting Part of Swift Computed Structure

I was wondering if this behavior in the swift language is documented anywhere. I haven't been able to find it in the official documentation. It is best expressed in code:
var testBacking = CGPoint(x: 3, y: 5)
var testPoint:CGPoint {
get {
print("getter called")
return testBacking
} set {
print("setter called with newValue = \(newValue)")
testBacking = newValue
}
}
testPoint.x = 10 // getter called
// setter called with newValue = (10.0, 5.0)
As you can see, I am only setting the x component of the computed structure testPoint, and in doing so, swift automatically calls the getter first and pulls out the y component and builds a complete structure that it then passes to the setter as newValue. This seems like appropriate behavior. My question is: Where is this behavior documented? Have I missed it, or is it simply not mentioned?
The way to understand this is to consider a similar but simpler case without your extra complications. Let's just talk about this:
struct S {
var name = "matt"
}
var s = S()
s.name = "mogelbuster"
How does that work? What happens when we set s.name? First, pull out the current value of s; then, we set its name property; then, we set the value of s to this new struct. (You can easily confirm that last part by putting a setter observer on s.)
Setting a struct's property by way of a reference, then involves getting the reference's value (the struct), setting the property, and setting the reference's value with the new struct. That's because a struct is a value type. It cannot be mutated in place, so setting a property by way of a reference to a struct involves setting into the reference.
What you are doing with testPoint is merely a computed-variable version of the same process. The mere act of speaking of testPoint.x means that we must get testBacking, to find out what it is. Thus, the getter is called. Then you set into testPoint.x, thus calling the setter to write the new value back into testBacking.
Note that the same thing would not be true if we were working with a class. Here's a variation on your original example:
class PointHolder {
var point = CGPoint(x:3, y:5)
var x : CGFloat {
get { return point.x }
set { point.x = newValue }
}
}
var testBacking = PointHolder()
var testPoint:PointHolder {
get {
print("getter called")
return testBacking
} set {
print("setter called with newValue = \(newValue)")
testBacking = newValue
}
}
testPoint.x = 10 // getter called, but _not_ setter
In the last line, the testPoint setter is not called — because a class instance is a reference type and is mutable in place. testBacking is changed without setting, because what we got from testBacking when we said testPoint.x, and the getter was called, is a reference; a change to this changes the thing testBacking points to without setting into it.

Self in protocol always need to be optional?

Example:
internal protocol PropertyProtocol {
var property: Self {
get
}
}
The only option I see to implement it, let us say in a class is
internal final class PropertyClass: PropertyProtocol {
let property: PropertyClass
internal init(otherOne pOtherOne: PropertyClass) {
self.property = pOtherOne
}
}
But then I do not see a possibility to use it.
let test: PropertyProtocol = PropertyProtocol(...) // hmm, how?
Does Self in a protocol property type declaration always have to be optional?
As a stored property, indeed it would have to be optional for you to create an instance, as each instance would require the stored property to be assigned during initialisation – leading to recursive behaviour. Therefore Self doesn't make too much sense as a stored property; it's really more designed to be used with methods or calculated properties.
Depending on what you're using this for (seems like a fairly hypothetical example), you could implement a calculated property like so:
protocol PropertyProtocol {
var property : Self { get }
}
final class PropertyClass : PropertyProtocol {
var property : PropertyClass {
get {
return // ...
}
set {
// ...
}
}
}
That way the class itself can manage the creation of the property when it's accessed, preventing the recursive behaviour of requiring it to be assigned during initialisation.

Why do we use the keyword "get" in Swift variables declaration?

This might sound dumb, but I can't figure out why programmers declare variables in Swift as follows:
class Person: NSObject {
var name: String { get }
}
Why is the keyword "get" used? Why is "set" missed? I thought we used them like this:
class Person: NSObject {
var name: String {
get {
// getter
}
set {
// setter
}
}
}
This might be a spam question, but I am interested in the theoretical definition of { get }
Sentences such as var name: String { get } are normally used in protocols not in classes. In a protocol it means that the implementation must have a variable of type String which should be at least read only (hence the get). Had the curly brackets bit been { get set } the variable would have been read write.
Actually as per Earl Grey answer, var name: String { get } will not compile inside a class.
The first code example strictly speaking doesn't make sense. You do not declare variables like this in a class.. (You do it in a protocol like this.)
The second is an example of computed property,though the getter and setter implementation is missing. (it seems to be implied at least so I won't object about validity of the code example.)

Using Swift Computed Properties Vs. Accessor and Mutator Functions

Coming from a Java background where getters and setters are commonly used to provide a public interface for private fields, I see computed properties in swift as an integrated modification of such accessor and mutator methods. I understand that computed properties are designed to modify or retrieve the value of any other field, while providing functionality for additional code.
Given that Swift computed properties appear to have the same purpose and usage of Java getters and setters, would there be any significant performance difference in the following swift declarations? Is there any performance advantage using computed properties over accessors and mutators?
Computed property
private var privateField: Int = 0
var field: Int { get { return privateField } set { privateField = newValue } }
Getter / Setter
private var privateField: Int = 0
func getField() -> Int {
return privateField
}
func setField(newValue: Int) {
privateField = newValue
}
In terms of readability, I personally think the separate methods approach looks neater and more organized, and if there were no performance issues I would use it over get {} set {}
The key here is to write idiomatic Swift code; a property in Swift is expected to be:
var field: Int = 0 {
didSet {
//Any consequences of setting here
}
}
Your getField()/setField() solution is unusual and not an expected use of the language. Readability is the most important aspect here, but this aligns with performance: I'm sure as the language is further developed and optimized, it will definitely ensure that its own idiomatic code continues to run quickly, but it may not care about the performance of your getField()/setField().

Idiomatic Swift: Getter & Setter boiler plate coding

While migrating some projects from Objective-C to Swift, I find myself replacing the #property/#synthesize syntax with a lot more boiler-plate code.
For example, for every #property I am implementing, I currently use this pattern:
var foo: Foo? {
get {
return _foo
}
set {
_foo = newValue
}
}
var _foo: Foo?
It ends up adding quickly. Compare this with the 2 lines in Objective-C. That doesn't feel right.
Should I just replace the code using _foo in my ported classes with foo and skip the abstraction of each public var behind an interface entirely?
As #Amit89 pointed out, you can simply use _foo.
In your example, adding foo does exactly nothing, as you simply recreated the get and set functionality already supplied with _foo.
If you want to control how _foo is set you can use property observers:
var _foo: Foo? {
didSet { }
willSet { }
}
If you want to control how _foo is retrieved, then it would indeed make sense to create a private version of _foo, and then accessing it via a computed property:
private var _foo: Foo?
var foo: Foo? {
get {
// return `_foo` in some special way
}
// add a setter if you want to set `_foo` in some special way
}