Jump to content
chkaufmann

Identify "reference to procedure"

Recommended Posts

I create a handler where I want to subscribe / unsubscribe consumers:

type
  TBSEvent<T> = reference to procedure(const obj: T);

  IBSRemoteMessageController = interface
  ['{1C7ECC50-3CA2-41A0-B230-0E9FE4CF9BE4}']
    procedure Subscribe(AHandler: TBSEvent<IBSRemoteMessage>);
    procedure Unsubscribe(AHandler: TBSEvent<IBSRemoteMessage>);
  end;

Now in my implementation of IBSRemoteMessageController I keep a list of these events. Unfortunately it looks like when I try to Unsubscribe() I get a different pointer even if I pass the same method.

The only solution I see here is, that I return a key with the Subscribe() method and then pass this key to Unsubscribe(). Or is there a different solution for this problem?

 

Regards
Christian

Edited by chkaufmann

Share this post


Link to post
2 minutes ago, chkaufmann said:

I create a handler where I want to subscribe / unsubscribe consumers:


type
  TBSEvent<T> = reference to procedure(const obj: T);

  IBSRemoteMessageController = interface
  ['{1C7ECC50-3CA2-41A0-B230-0E9FE4CF9BE4}']
    procedure Subscribe(AHandler: TBSEvent<IBSRemoteMessage>);
    procedure Unsubscribe(AHandler: TBSEvent<IBSRemoteMessage>);
  end;

Now in my implementation of IBSRemoteMessageController I keep a list of these events. Unfortunately it looks like when I try to Unsubscribe() I get a different pointer even if I pass the same method.

The only solution I see here is, that I return a key with the Subscribe() method and then pass this key to Unsubscribe(). Or is there a different solution for this problem?

 

Regards
Christian

If I understand this correctly a "reference to procedure" type is implemented by the compiler as a hidden class with an interface that contains the actual method called when the referenced method is called through this reference. On the point where you pass the reference the compiler creates an instance of the class and uses it to store all captured variables the method refers to. In your case that happens two times, at the point where you call Subscribe and again when you call Unsubscribe, so you get two different instances of the hidden class passed to your methods (actually you get interface references, not object references).

 

I have no idea whether this will work, but since you can cast an interface reference to an object reference to get the object implementing the interface do that on the aHandler and compare the Classtype of that object with the one obtained from the stored handler in the same manner.

Share this post


Link to post
33 minutes ago, chkaufmann said:

The only solution I see here is, that I return a key with the Subscribe() method and then pass this key to Unsubscribe().

Actually I prefer this method anyway. It is simple, deterministic and failure proof.

  • Like 2

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×