On 05/10/16 16:26, Marcos Douglas wrote:
Tony Whyman had posted on August 10 a problem with the compiler using Delegates.
He used a workaround to "solve" his problem and the thread died.

Marcos,

I believe I concluded that this could be a bug or feature. Either way it is a Bear Trap waiting for the unwary programmer and it would be nice if in some way the implementation could be improved. The problem, as I see it is:

Basics:

1. Whenever an interface reference is coerced from an interfaced object, the object's reference count is incremented.

2. When the interface is copied that reference count is again incremented.

3. When the interface goes out of scope, the reference count is decremented and when it reaches zero, the object is freed.

So far so good, but, when you have a delegated interface:

Terminalogy: In the example:

    TMyValue = class(TInterfacedObject,IValue);

    TMyObject = class (TinterfacedObject,IMyInterface)
    ...
    property Value: IValue read FValue implements IValue;
    end;

    Then a TMyValue object "is the source of" the delegated interface.
    A TMyObject object "provides" the delegated interface.

4. Whenever an interface reference to a delegated interfaced is coerced from an interfaced object, it is the reference count of the object that "is the source of" the delegated interface that is incremented.

5. When the interface is copied the reference count of the object that "is the source of" the delegated interface is incremented.

6. When the interface goes out of scope, the reference count of the object that "is the source of" the delegated interface is decremented and when it reaches zero, that object is freed.

7. You are responsible for freeing the object that "provides" the delegated interface.

To me this is counter-intuitive behaviour and this counter-intuitiveness is compounded by the case where:

a. An interfaced object provides only a delegated interface.

b. An inherited interface (e.g. IUnknown) is coerced from the object.

In this case, the reference count incremented is that of the object that "provides" the delegated interface and not the object that "is the source of" the delegated interface.

Where do we go from here?
======================

Provided you understand what is happening then it works - but there is no real documentation and it is really easy to get this wrong.

For me the consistent approach should be that when you coerce an interface from an object, the reference count of the object that "provides" the delegated interface is always the one that is incremented and the interface remains tied to that object An object that "is the source of" a delegated interface should always have its lifetime tied to that of the object that "provides" the delegated interface. i.e. it has an implicit reference to the object that is the source of the interface.

Tony Whyman
MWA

_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to