Starting from Delphi Berlin the weak attribute was invented. Which informs the compiler so that it does not call the _Release when going out of scope (scope finalization code generated).
This is very useful when you use VCL components as the implementations of certain interfaces and then pass them somewhere. And sometimes in the places where you use the interface you can get AV, because of the object destruction order or any other similar reason.
So wherever you use such references just do the folowing code just before it goes out of scope:
System.Initialize (MyWeakIntfRef);
This will safely clear the reference without calling the _Release.
Read about weak there.
afaik the weak attribute exists since XE3 😉
LikeLike
Yes. But the compiler support in Win32 is ONLY from Berlin.
You can read about that there.
LikeLike
Your original analysis of what Weak does it incomplete, it does not only prevent calling _Release but also calling _AddRef when assigning.
So what System.Initialize (by the way Pointer(MyWeakIntfRef) := nil would have been sufficient) would do in your case is cause a memory leak because the initial assignment to MyWeakIntfRef most likely increased the RefCount.
FWIW: there are some weak reference implementations for interfaces around – including the one in Spring4D 1.2 (yet another goodie you have to wait for ^^)
LikeLike
That was used as I said with forms and frames which implements the interfaces. Mostly legacy code. And there you have no memory leak because of doing Initialize as they are not reference counted.
And usually its just Initialize(MyWeakRef) – which looks better than “Pointer(MyWeakRef) := nil”.
I wrote System.Initialize so that everyone knows in which unit it is.
LikeLike
If they are not reference counted there is no use in setting them to nil yourself because _Release would not do anything. However if the instance it was pointing to was destroyed in the meanwhile then it makes sense though.
Which is the most important feature of weak references: they are getting niled automatically when the original instance gets freed.
LikeLike
Exactly. The instance was already destroyed, but the field in another form/frame was pointing to the destroyed instance.
By the way weak works similar to components in Delphi. As once the component is a published field of the parent and I just call Free on a component itself – it does clears the field reference itself as well (but that’s you know is not a compiler backed up, but just code written in Destroy of the component).
LikeLike
I think in such case I would rather use [Unsafe] in Berlin because the housekeeping related to weak would not be necessary here.
FWIW Marco wrote about that some while ago:
http://blog.marcocantu.com/blog/2016-april-weak-unsafe-interface-references.html
LikeLike
Pre Berlin 🙂 Most of us are not yet on Berlin…
LikeLike