2008-11-14 16 views
8

Aşağıdaki kodu çalıştırırken neden EAccessViolation kaldırılır? Yukarıdaki kod TForm1 kullanılanTList.Remove() neden bir EAccessViolation hatası üretiyor?

uses 
    Generics.Collections; 
    ... 

var 
    list: TList<TNotifyEvent>; 
    ... 

begin 
    list := TList<TNotifyEvent>.Create(); 
    try 
    list.Add(myNotifyEvent); 
    list.Remove(myNotifyEvent); // EAccessViolation at address... 
    finally 
    FreeAndNil(list); 
    end; 
end; 

procedure myNotifyEvent(Sender: TObject); 
begin 
    OutputDebugString('event'); // nebo cokoliv jineho 
end; 

cevap

0

...

uses 
    Generics.Collections; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    list: TList<TNotifyEvent>; 
begin 
    list := TList<TNotifyEvent>.Create(); 
    try 
    list.Add(myNotifyEvent); 
    list.Remove(myNotifyEvent); // EAccessViolation at address... 
    finally 
    FreeAndNil(list); 
    end; 
end; 
procedure TForm1.myNotifyEvent(Sender: TObject); 
begin 
    OutputDebugString('event'); // nebo cokoliv jineho 
end; 
+0

Hmm, bu sizin sorunuzun cevabı değil. Sorunuzdaki kodla (ki şimdi olduğu gibi geçersizdir, çünkü buradaki "myNotifyEvent" ifadesi, "TNotifyEvent" imzasıyla eşleşmediğinden geçersiz olacaktır.) –

5

Bir böcek gibi görünüyor.

Hata ayıklama dcu'larıyla derlerseniz (normalde bunu aklınızı kaybetmek istemediğiniz sürece yapmayın!) Karşılaştırıcıya yapılan bir aramanın yanlış gittiğini görürsünüz. Karşılaştırma işlevinin bir (isteğe bağlı) üçüncü değeri ayarlanmaz ve erişim ihlaline neden olur.

Belki de yöntem işaretleyicilerini genel bir listeye koyamazsınız.

Tamam aşağıdaki çalışır:

Sen possiby biraz daha zeka ;-) ile, kendi karşılaştırıcısı tanımlamak zorunda
uses 
    Generics.Defaults; 

type 
    TForm4 = class(TForm) 
    ... 
    private 
    procedure myNotifyEvent(Sender: TObject); 
    end; 

TComparer<T> = class (TInterfacedObject, IComparer<T>) 
public 
    function Compare(const Left, Right: T): Integer; 
end; 

implementation 

uses 
    Generics.Collections; 

var 
    list: TList<TNotifyEvent>; 
begin 
    list := TList<TNotifyEvent>.Create(TComparer<TNotifyEvent>.Create); 
    try 
    list.Add(myNotifyEvent); 
    list.Remove(myNotifyEvent); 
    finally 
    FreeAndNil(list); 
    end; 
end; 

procedure TForm4.myNotifyEvent(Sender: TObject); 
begin 
    ShowMessage('event'); 
end; 

{ TComparer<T> } 

function TComparer<T>.Compare(const Left, Right: T): Integer; 
begin 
    Result := 0; 
end; 

.

+0

Bana da bir hata gibi: –

1

Özel bir karşılaştırıcıyı TList<T>'a geçirmek mümkün mü? Önümde D2009 yok, o yüzden deneyemezsin.

+0

Evet, aşırı yüklenen kurucudan birini geçebilirsiniz –

3

Erişim İhlali, eksik karşılaştırma nedeniyle oluşur. Bunun bir yama giderilmiştir zanlısı ancak bir TObjectList kullanırsanız sorun hala ben sadece en basit çözümü ile güncelliyorum böylece (en azından 2009 Delphi) devam:

TList<TNotifyEvent>.Create(TComparer<TNotifyEvent>.Default); 

ya da benim durumumda

yılında
TObjectList<TNotifyEvent>.Create(TComparer<TNotifyEvent>.Default); 
+0

bu hata hala xe4 ile /: –

İlgili konular