2011-01-13 30 views
7

tôi đã gặp lỗi khác trong ứng dụng do sử dụng bất cẩn giao diện Delphi. Khi tôi truyền một giao diện đến một thủ tục bỏ qua đối số đó, cá thể đó sẽ không bao giờ được giải phóng. Xem ví dụ đơn giản sau:Tham chiếu giao diện không sử dụng không bị phá hủy

ITest = interface 
    procedure Test; 
end; 

Tester = class(TInterfacedObject, ITest) 
public 
    procedure Test; 
end; 

Base = class 
public 
    procedure UseTestOrNot(test : ITest); virtual; abstract; 
end; 

A = class(Base) 
public 
    procedure UseTestOrNot(test : ITest); override; 
end; 

B = class(Base) 
public 
    procedure UseTestOrNot(test : ITest); override; 
end; 

{ A } 

procedure A.UseTestOrNot(test: ITest); 
begin 
    test.Test(); 
end; 

{ B } 

procedure B.UseTestOrNot(test: ITest); 
begin 
    WriteLn('No test here'); 
end; 

// -------- Test --------------------------------------- 
var 
    list : TObjectList<Base>; 
    x : Base; 
    t : ITest; 
begin 
    ReportMemoryLeaksOnShutdown := true; 

    list := TObjectList<Base>.Create; 
    list.Add(A.Create); 
    list.Add(B.Create); 

    // 1 x Tester leak for each B in list: 
    for x in list do 
     x.UseTestOrNot(Tester.Create); 

    // this is ok 
    for x in list do 
    begin 
     t := Tester.Create; 
     x.UseTestOrNot(t); 
    end; 

    list.Free; 
end. 

Bạn có thể giải thích điều gì xảy ra với bộ đếm tham chiếu không? Bạn có thể đưa ra bất kỳ hướng dẫn/hướng dẫn nào tốt nhất (như "Không bao giờ tạo ra một cá thể giao tiếp bên trong một cuộc gọi hàm [nếu bạn không biết điều gì xảy ra bên trong]"

Giải pháp tốt nhất tôi có thể nghĩ là viết một phương pháp mẫu trong lớp cơ sở đó giúp tiết kiệm phân biển kiểm tra thông qua và kêu gọi một DoUseTestOrNot phương pháp trừu tượng.

EDIT Delphi 2010

+0

Phiên bản Delphi này là gì? –

+1

xin lỗi, đó là Delphi 2010 – hansmaad

+0

Không quan trọng, đó là lỗi bất kể phiên bản. chờ cho đến khi delphi cũ 2? Chúc mừng – APZ28

Trả lời

8

Đó là một biểu hiện khác của các lỗi here.
Tôi sẽ thêm điều này vào báo cáo QC.

Điều này không tái tạo trong bản cập nhật XE Delphi 1 nữa.

--jeroen

+0

chỉ là một lỗi khác, grrr – hansmaad

+0

Đối với hồi quy: bạn có thể gửi cho tôi một chương trình điều khiển đầy đủ chức năng (.dpr) hiển thị rò rỉ bộ nhớ trong Delphi 2010 - tốt hơn với FastMM? Bất cứ điều gì tại pluimers dot com hoạt động, chỉ cần bắt đầu với tên đầu tiên của tôi. Bằng cách đó tôi có thể loại trừ bất kỳ lỗi chính tả nào mà tôi đã thực hiện từ việc biên dịch mã trên. –

8

Thêm một để bạn khai ITest guid

ITest = interface 
['{DB6637F9-FAD3-4765-9EC1-0A374AAC7469}'] 
    procedure Test; 
end; 

Thay đổi vòng lặp này

for x in list do 
    x.UseTestOrNot(Tester.Create as ITest); 

Các GUID là neccesary để có thể sử dụng as

Test.Create as ITest làm cho trình biên dịch để thêm việc phát hành nơi các đối tượng được tạo ra đi ra khỏi phạm vi.

+0

+1; Đây là giải pháp tốt cho đến khi lỗi được sửa. –

+0

Và: nó được cố định trong bản cập nhật xe Delphi XE hoặc Delphi XE 1. –

+0

Cảm ơn bạn đã giải quyết sự cố này. Có bất kỳ mục nhập hoặc nút menu nào để chèn GUID không? Tôi luôn luôn quên phím tắt, vì tôi không bao giờ sử dụng GUID (tôi luôn cố gắng tránh như và là vv). – hansmaad

Các vấn đề liên quan