private weak var _delegate: SomeClassDelegate?
weak var delegate: SomeClassDelegate? {
get {
return _delegate
}
set {
_delegate = newValue
}
}
This is valid code. Is there is any sense in using weak
keyword with computed delegate
property? Logically no; how compiler will process through this code?
A computed property’s dependencies are reactive values that are used to determine the value of the computed property. If none of these dependencies change, the cached value will be returned. If the reactive values change, it will trigger the computed property to re-compute the modified value.
While computed properties are a form of syntactic sugar, they have several benefits. You can make a property dependent on other information, avoiding inconsistent states. You can hide functionality behind a simple interface. The caller can use a computed property as if it was a real one.
1 Stored Properties ¶. In its simplest form, a stored property is a constant or variable that’s stored as part of an instance of a particular class or structure. 2 Computed Properties ¶. ... 3 Property Observers ¶. ... 4 Property Wrappers ¶. ... 5 Global and Local Variables ¶. ... 6 Type Properties ¶. ...
But Swift also allows computed properties that accept new values. The get and set keywords define a getter and a setter for a computed property. The setter takes a new value and calculates the end date. Again, we could have done the same with a method. But computed properties are better because, from the outside, they look like any other property.
Is there is any sense in using
weak
keyword with computed delegate property?
Not only is it sensible to do so, but it’s important to do so. This computed property is your public interface to this private hidden property. If the computed property lacks the weak
qualifier, callers will draw incorrect conclusions about the underlying semantics.
Consider:
class SomeClass {
private weak var _delegate: SomeClassDelegate?
var delegate: SomeClassDelegate? { // whoops; this should be `weak`
get { return _delegate }
set { _delegate = newValue }
}
}
And
class CustomDelegate: SomeClassDelegate { ... }
Then
let object = SomeClass()
object.delegate = CustomDelegate()
In the absence of the the weak
qualifier on the computed property and without diving into the implementation details, the programmer might incorrectly conclude that the above is fine. But it’s not. Because the underlying _delegate
is weak
, this CustomDelegate()
instance will be deallocated immediately, and the object will end up with no delegate object. And there’s no compiler warning about this behavior.
If, however, we fix SomeClass
like so:
class SomeClass {
private weak var _delegate: SomeClassDelegate?
weak var delegate: SomeClassDelegate? { // great; matches underlying semantics
get { return _delegate }
set { _delegate = newValue }
}
}
Then the programmer will receive a very helpful warning:
let object = SomeClass()
object.delegate = CustomDelegate() // results in "Instance will be immediately deallocated because property 'delegate' is 'weak'"
They’ll then correctly deduce that they should keep their own strong reference to this CustomDelegate
for the code to work properly.
So, bottom line, you don’t technically need the weak
qualifier on the computed property that is backed by a private weak
stored property, but it’s prudent to do so to avoid mysterious bugs and/or misunderstandings about the underlying semantics.
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