You seem to be playing around with words. Perhaps I am guilty of sloppy English when I say "interface is copied" when meaning "an interface reference is copied". However, this does not change the underlying problem.

The problem being referred to is the functionality described here:

http://freepascal.org/docs-html/current/ref/refse44.html#x98-1200007.4

under the title "Interface delegation". The word "contained" does not appear here. Maybe it should, but it doesn't. If TContainedObject does indeed solve the problem then it would be useful to have it documented and, if so, for interface delegation using a TInterfacedObject subclass to be at least deprecated and may be even barred.

The problem is that this is Rabbit Hole and it needs filling in otherwise more will fall down it.


On 07/10/16 10:31, stdreamer wrote:
On 05/10/2016 19:13 μμ, Tony Whyman wrote:
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.
I'm guessing that by "coerced" you mean "reference a contained interface".

2. When the interface is copied that reference count is again incremented.
Interface can not be copied only implement objects can be copied and when they are their interface counter has nothing to do with the original interface, in fact it is the exact opposite, after a copy you need to make sure that the counter has been reset, which leads to believe that I misunderstood something.

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.

That is not a delegated interface that is a contained interface.

A delegated interface goes something like this

  IValue = interface
  ['{72D8B44F-5834-425D-AB3A-45785E94E2E4}']
    function AsString:string;
  end;

  IMyInterface = interface
   ['{5E04F587-E4A0-42A7-850C-74C882BB5958}']
   procedure DoSomething;
  end;

  //tmyvalue can inherit from tContainedobject
  //for simplification.
  TMyValue = class(TInterfacedObject, IValue)
    function AsString:String;
  end;
  //IValue must be part of TMyObject not a simple property.
  TMyObject = class(TInterfacedObject, IMyInterface, IValue)
  private
    property MyValue :TMyValue implements IValue;
  end;

Τhe problem of a contained interface has already been solved, see the TContainedObject. To sum it up a contained object reference counting mechanism increments and decrements the container's reference counter it does not have a life of its own.

Sorry the rest look like a rabbit hole based on the wrong assumptions to me, there might be some merit but I have no will to search for it.


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


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

Reply via email to