I raised this topic long time ago, in this GitHub PR.
Main concerns remain the same. You are still able to add weak attribute to a computed property and it is absolutely unclear whether it will affect anything and if yes - in what way.
Maybe we should forbid it completely or at least raise a warning about redundancy?
The only case where I can see it being useful is as a kind of documentation for the behavior of a computed property:
class Thing {
private weak var _delegate: SomeDelegateType?
// 'weak' here does nothing for the compiler, but it does
// document to callers that the property is stored weakly
weak var delegate: SomeDelegateType? {
get { return _delegate }
set {
if (self.delegateIsAcceptable(newValue)) { _delegate = newValue }
}
}
}
I don't know if that's a good reason to continue allowing weak on computed properties, though.
It's at least partially one of those cases where Objective-C allows it, so Swift allows it too. As far as I know it's mostly for the reason BJ brought up.
(There's an unfortunate part where it may be required in Objective-C because a protocol requirement might specify that a property is weak, even though the implementation is computed.)
I think this is an oversight. I agree with @Chris_Lattner3 that at this stage it is best to add a warning, just like we do for weak on protocol requirements. In fact it should be easy to generalize the existing code for doing that.
I would suggest skipping the evolution proposal unless somebody objects.
Do you want to file a bug or even attempt an implementation?
Excuse me if I jump here with a not-quite-about-Swift rant.
In Obj-C, there isn't really anything that could be called a "weak" or a "strong" property. The property value (in this case) is a reference to an object, and there's no such thing as a weak or strong reference. It is variables (storage locations) that are weak or strong, not references (pointer values).
Unfortunately, people rely on their intuitions and still think there are weak and strong references, and this contaminates even discussions about Swift.
The significance of "weak" or "strong" on an Obj-C property is that it affects what kind of instance variable the compiler generates if it synthesizes the property — that is to say, if the property is what Swift would call a stored property.
This is only controversial — there was a long discussion about this on the old cocoa-dev list years ago —because some people insisted that calling an Obj-C property "weak" or "strong" is a kind of API contract — that the underlying implementation really does not or really does keep an owning reference to the object, somewhere in its dark interior, and that clients of the class are allowed to make decisions based on this supposed contract.
However, this is all truly an implementation detail, and (IMO) a bad one because of the confusion it engendered in the Obj-C world.
Having said all that, I think @jrose is still correct, that we can't change this in Swift — for @objc protocol methods — for potential source compatibility reasons, though not for functional reasons. This is a case where Swift has to continue to be a little bit broken because (IMO) Obj-C is.
I don't think we need to allow silly things in Swift just to allow precise control of the unnecessary annotations produced in the exported Objective-C interface.
I initially bristled at this, because memory semantics of entity relationships are definitely not an implementation detail. For example, the delegate pattern in Cocoa depends heavily on objects not owning their delegates. The zeroing-ness of zeroing weak references also has API implications here.
On the other hand, there are many entity relationships that aren’t exposed as properties. In our code base, we have a widespread addObserver/removeObserver pattern – essentially multicast delegates – where observers are held weakly through a collection, and this has to be expressed through documentation and convention rather than annotations, just as the delegate pattern used to be.
Being able to express memory semantics of entity relationships in general wouldn’t necessarily be silly, but it would require something far more expressive than property annotations. As such keeping the latter around because the former might be nice is probably a bad idea.
I think this is overly pedantic hair-splitting. Not only is "weak reference" a perfectly reasonable term for the existence of a reference that does not keep the object alive (it even has a runtime representation in Swift!), but the API contract of strong vs. weak (Cocoa terminology that predates ARC or even ObjC GC) is important in reasoning about your object graph.
This is pushing me towards keepingweak on computed properties in Swift.