Okay ich habe scheinbar die IInterfaces noch nicht ganz verstanden.
Hier ist mein Konzept:
Delphi-Quellcode:
type
TNewspaper = class
private
FTitle : String;
procedure SetTitle(const Value : String);
public
property Title : String read FTitle write SetTitle;
end;
ISubscriber = interface
procedure GetNewspaper(Newspaper : TNewspaper);
end;
TPublisher = class
protected
Subscribers : TList<ISubscriber>;
public
constructor Create;
procedure AddSubscriber(Subscriber : ISubscriber); virtual; abstract;
procedure RemoveSubscriber(Subscriber : ISubscriber); virtual; abstract;
procedure SendNewsToAllSubs; virtual; abstract;
end;
Hier sind ein paar konkrete Klassen:
Delphi-Quellcode:
type
TFAZ = class(TPublisher)
private
FCurrentNewspaper : TNewspaper;
procedure SetCurrentNewspaper(const Value: TNewspaper);
function GetCurrentNewspaper : TNewspaper;
public
procedure AddSubscriber(Subscriber : ISubscriber); override;
procedure RemoveSubscriber(Subscriber : ISubscriber); override;
procedure SendNewspaperToAllSubs;
property CurrentNewspaper : TNewspaper read GetCurrentNewspaper write SetCurrentNewspaper;
end;
TFischer = class(TInterfacedObject, ISubscriber)
procedure GetNewspaper(Newspaper : TNewspaper);
end;
TMeier = class(TInterfacedObject, ISubscriber)
procedure GetNewspaper(Newspaper : TNewspaper);
end;
Zitat:
Wenn du im zuletzt geposteten Beispiel die Subscriber in einer TList speicherst, haust du dir u.U. den RefCount kaputt. Denn das AddSubscriber sorgt nur für eine weak Reference auf deinen Subscriber (es wird beim adden in die TList, welche ja nur Pointer aufnimmt, kein _AddRef durchgeführt). Wenn dieser Subscriber somit irgendwo out of scope läuft und (sofern du natürlich das automatische Refcounting von TInterfacedObject z.B. benutzt) freigegeben wird, hängt in deiner Subscriber Liste ein dangling Pointer und beim nächsten Zugriff darauf (z.B. durch MessageAllSubscribers) knallts.
Wie verwalte ich denn dann korrekter Weise meine Referenzen? Gibt es die Möglichkeit mir den Referenzzähler der Interface-Klasse zunutzen zu machen? Ist sowas sogar so gedacht? Wie würde ich das denn machen?
Grüße