2012-10-24 58 views
0

我想創建一個Tinterfacedobject,其中包含(ao)兩個屬性ObjectLinks和ObjectBacklinks。 Objectlinks包含對其他對象的接口引用,ObjectBacklinks包含這些鏈接如何創建包含對delphi中接口的弱引用的TDictionary

這兩個屬性由一個TWeakIntfDictionary =類(TDictionary) 反向鏈接屬性被保持在ObjectLinks.ValueNotify事件的反向

爲了確保當原始對象被釋放時,接口引用從字典中移除,通知算法(與TFmxObject使用相同)

懷疑我創建這麼多時遇到了各種循環引用問題引用相同的接口對象:(但我似乎無法擺脫這一點問題。當從被銷燬的對象調用FreeNotification時,一切都很好,直到它從FreeNOtification返回。在這一點上物體的.Destroy又被稱爲:-(

{1 Dictionary of interfaces (using weak references) using Free notification } 
    TWeakIntfDictionary = class(TDictionary<int64, IInterface>, IFreeNotificationMonitor) 
    protected 
    procedure ValueNotify(const Value: IInterface; Action: TCollectionNotification); override; 
    public 
    procedure FreeNotification(aObject: TObject); 
    end; 

    implementation 

    procedure TWeakIntfDictionary.FreeNotification(aObject: TObject); 
    var 
    lObj: TPair<int64, IInterface>; 
    begin 
    //Object is going to be destroyed, remove it from dictionary 
    for lObj in Self do 
    begin 
     if (lObj.Value as TObject).Equals(aObject) then 
     begin 
     Remove(lObj.Key); 
     Break; 
     end; 
    end; 
    end; 

    procedure TWeakIntfDictionary.ValueNotify(const Value: IInterface; Action: TCollectionNotification); 
    var 
    lDestrIntf: IFreeNotificationBehavior; 
    begin 
     // When a TObject is added to the dictionary, it must support IDestroyNotification 
     // This dictionary is than added to the notificationlist of the TObject 
    if Supports(Value, IFreeNotificationBehavior, lDestrIntf) then 
     case Action of 
     cnAdded:  begin 
         lDestrIntf.AddFreeNotify(Self); 
         lDestrIntf._Release; 
         end; 
     cnRemoved, 
     cnExtracted: begin 
         lDestrIntf.RemoveFreeNotify(Self); 
         end; 
     end 
    else 
     raise EWeakInftDictionaryException.Create('Object added to TWeakIntfDictionary does not support IFreeNotificationBehavior'); 

    inherited; 

    end; 

任何人都知道一個在WeakReferences詞典的現有實現的? 任何人任何建議,如何解決這個問題?

+3

如果這些是唯一的引用,則不需要弱引用當A引用B而B引用A時,需要引用弱引用您描述的是一個容器,其中包含對A和B,那裏沒有圓形。 –

+0

你之前沒有說過這個。我看不到任何有關雙重鏈接的證據。在這個問題上我看不出什麼特別的地方。 –

+0

第二句:「Objectlinks包含對其他對象的接口引用,ObjectBacklinks包含這些鏈接的反向」 – Bascy

回答

0

發現在該解決方案以下代碼

procedure TWeakIntfDictionary.FreeNotification(aObject: TObject); 
var 
    ... 
begin 
    //Object is going to be destroyed, remove it from dictionary 
    lSavedEvent := FDict.OnValueNotify; 
    FDict.OnValueNotify := nil; 
    lRemoveList := TList<TKey>.Create; 
    try 
    for lPair in FDict do 
    begin 
     pointer(lIntf) := lPair.Value; 
     if (lIntf as TObject) = aObject then 
     lRemoveList.Add(lPair.Key); 
    end; 
    pointer(lIntf):=nil; // avoid _release for the last item 

    for lKey in lRemoveList do 
     FDict.Remove(lKey); 

    finally 
    FDict.OnValueNotify := lSavedEvent; 
    lRemoveList.Free; 
    end; 
end; 
相關問題