2008-08-27 18 views
8

Trong một trong các hình thức VB6 của tôi, tôi tạo ra một số đối tượng Form khác và lưu trữ chúng trong các biến thành viên.Khi nào tôi phải đặt biến thành "Không có gì" trong VB6?

Private m_frm1 as MyForm 
Private m_frm2 as MyForm 

// Later... 
Set m_frm1 = New MyForm 
Set m_frm2 = New MyForm 

Tôi nhận thấy rằng tôi đang rò rỉ bộ nhớ bất cứ khi nào biểu mẫu (cha mẹ) được tạo và hủy. Tôi có cần gán các biến thành viên này cho Nothing trong Form_Unload() không?

Nói chung, khi nào cần thiết?

GIẢI QUYẾT: Rò rỉ bộ nhớ cụ thể này đã được sửa khi tôi thực hiện Unload trên các biểu mẫu được đề cập, chứ không phải khi tôi đặt biểu mẫu thành Nothing. Tôi quản lý để loại bỏ một vài rò rỉ bộ nhớ khác bằng cách rõ ràng thiết lập một số trường hợp của Class Module để Nothing, là tốt.

Trả lời

5

@Matt Dillard - Đã thiết lập những lỗi này để khắc phục sự cố rò rỉ bộ nhớ của bạn chưa?

VB6 không có bộ thu gom rác chính thức, dọc theo dòng của những gì @Konrad Rudolph nói.

Thực tế việc bỏ tải trên biểu mẫu của bạn dường như là cách tốt nhất để đảm bảo rằng biểu mẫu chính được làm sạch và mỗi biểu mẫu con dọn dẹp hành động của chúng.

Tôi đã thử nghiệm điều này với một dự án trống và hai biểu mẫu trống.

Private Sub Form_Load() 
    Dim frm As Form2 
    Set frm = New Form2 
    frm.Show 
    Set frm = Nothing 
End Sub 

Sau khi chạy cả hai biểu mẫu sẽ hiển thị. thiết lập frm thành không có gì tốt ... không có gì.

Sau khi xác định frm thành không có gì, tay cầm duy nhất mở cho biểu mẫu này là thông qua tham chiếu.

Unload Forms(1) 

Tôi có gặp sự cố chính xác không?

  • Josh
2

Nói đúng cách, nhưng nó mang lại cho người thu gom rác một gợi ý mạnh mẽ để làm sạch mọi thứ.

Theo quy tắc: làm điều đó mỗi lần bạn hoàn thành với đối tượng mà bạn đã tạo.

+1

Bộ thu gom rác thải là gì? VB 6 sử dụng tính toán tham chiếu ... –

+0

Tôi biết. Tôi chỉ có nghĩa là "điều mà deallocates trường hợp không sử dụng" Có thể là một quá trình riêng biệt mà không ưa thích công cụ như lão hóa, vv Nó vẫn còn làm sạch bộ nhớ. Chỉ thực sự xấu :) –

+0

@AllainLalonde: "Nói đúng ra", nó không phải là một bộ thu gom rác, và không có quá trình riêng biệt khác trong VB6. – GiddyUpHorsey

2

Đặt tham chiếu VB6 thành Không có gì, giảm số lần đếm lại mà VB có cho đối tượng đó. Nếu và chỉ khi số đếm bằng không, thì đối tượng sẽ bị hủy.

Đừng nghĩ rằng chỉ vì bạn thiết lập để có gì nó sẽ được "thu gom rác thải" như thế nào trong .NET

VB6 sử dụng một bộ đếm tham khảo.

Bạn được khuyến khích đặt thành "Không có gì" đối tượng instanciated tham chiếu đến mã C/C++ và các nội dung tương tự. Đã lâu rồi kể từ khi tôi chạm vào VB6, nhưng tôi nhớ đã đặt các tệp và tài nguyên thành không có gì.

Trong cả hai trường hợp, nó sẽ không bị tổn thương (nếu nó không có gì), nhưng điều đó không có nghĩa là đối tượng sẽ bị hủy.

VB6 có câu lệnh "With/End With" đã hoạt động "như" câu lệnh Using() trong C# .NET. Và tất nhiên, bạn càng có ít thứ toàn cầu, thì tốt hơn cho bạn.

Hãy nhớ rằng, trong cả hai trường hợp, đôi khi việc tạo một đối tượng lớn thì đắt hơn việc giữ một tham chiếu còn sống và sử dụng lại nó.

+0

Từ khóa 'Using' trong C# không giống như khối' With' của VB6. 'Sử dụng' là để triển khai' IDisposable' và VB6 không có tính năng tương tự. – GiddyUpHorsey

+0

Chính xác, do đó "dấu ngoặc kép" xung quanh "như". Nó giống như nó, nhưng nó không có gì để làm với thực tế đằng sau hậu trường. –

2

Tôi gặp sự cố tương tự như vậy trong khi quay lại. Tôi dường như nghĩ rằng nó cũng sẽ ngăn chặn các ứng dụng đóng cửa, nhưng nó có thể được áp dụng ở đây.

tôi kéo lên mã cũ và nó trông giống như sau:

Dim y As Long 
For y = 0 To Forms.Count -1 
    Unload Forms(x) 
Next 

Nó có thể là an toàn hơn để Dỡ bỏ các m_frm1. và không chỉ đặt nó thành không có gì.

4

@ Martin

VB6 đã có một "Với/End With" tuyên bố mà làm việc "như" Sử dụng() tuyên bố trong C# .NET. Và tất nhiên, bạn càng có ít thứ toàn cầu, thì tốt hơn cho bạn.

Với/End Với không làm việc như Sử dụng tuyên bố, nó không "Vứt" ở phần cuối của báo cáo kết quả.

Với/Kết thúc Với công việc trong VB 6 giống như trong VB.Net, về cơ bản nó là một cách để tắt thuộc tính đối tượng/phương thức gọi. ví dụ.

Với aCustomer .FirstName = "John" .LastName = "Smith" kết thúc với

7

Trên thực tế, VB6 thực hiện RAII giống như C++ có nghĩa là địa phương công bố tài liệu tham khảo tự động được thiết lập để Nothing ở phần cuối của một khối. Tương tự, nó nên tự động đặt lại các biến lớp thành viên sau khi thực hiện Class_Terminate. Tuy nhiên, đã có một số báo cáo rằng điều này không được thực hiện một cách đáng tin cậy. Tôi không nhớ bất kỳ thử nghiệm nghiêm ngặt nào nhưng thực tế luôn là cách tốt nhất để đặt lại biến thành viên theo cách thủ công.

+4

Tôi nghi ngờ rằng những tin đồn về nó không đáng tin cậy có nhiều khả năng là kết quả của các nhà phát triển mất theo dõi tài liệu tham khảo của họ. Tôi đã được mã hóa trong VB6 trong 10 năm và thời gian duy nhất tôi đã cần thiết để rõ ràng cần thiết để thiết lập một đối tượng để không có gì là để ngăn chặn chu kỳ. –

4

Đối tượng trong VB có tính tham khảo. Điều này có nghĩa là một đối tượng sẽ đếm số lượng các biến đối tượng khác có tham chiếu đến nó. Khi không có tham chiếu đến đối tượng, đối tượng là rác được thu thập (cuối cùng). Quá trình này là một phần của đặc tả COM.

Thông thường, khi một đối tượng được khởi tạo cục bộ nằm ngoài phạm vi (ví dụ: thoát khỏi phụ), số tham chiếu của nó sẽ giảm đi một, nói cách khác biến tham chiếu đối tượng bị hủy. Vì vậy, trong hầu hết các trường hợp, bạn sẽ không cần phải đặt rõ ràng một đối tượng bằng Không có gì khi thoát khỏi một Sub.

Trong tất cả các trường hợp khác, bạn phải đặt rõ ràng biến đối tượng thành Không có gì, để giảm số tham chiếu của nó (một). Đặt một biến đối tượng thành Không có gì, sẽ không nhất thiết phá hủy đối tượng, bạn phải đặt TẤT CẢ các tham chiếu thành Không có gì. Vấn đề này có thể trở nên đặc biệt cấp tính với cấu trúc dữ liệu đệ quy.

Một dấu hiệu khác, là khi sử dụng từ khóa Mới trong khai báo biến đối tượng. Một đối tượng chỉ được tạo khi sử dụng lần đầu tiên, không phải tại thời điểm từ khóa mới được sử dụng.Sử dụng từ khóa mới trong khai báo sẽ tạo lại đối tượng vào lần sử dụng đầu tiên mỗi lần số tham chiếu của nó chuyển thành 0. Vì vậy, thiết lập một đối tượng để Không có gì có thể phá hủy nó, nhưng đối tượng sẽ tự động được tạo lại nếu được tham chiếu lần nữa. Lý tưởng nhất là bạn không nên khai báo bằng cách sử dụng từ khóa mới, nhưng bằng cách sử dụng toán tử New mà không có hành vi phục sinh này.

2

Một điểm quan trọng chưa được đề cập ở đây là thiết lập đối tượng tham chiếu đến Không có gì sẽ làm cho đối tượng hủy của đối tượng chạy (Class_Terminate nếu lớp được viết bằng VB) nếu không có tham chiếu khác cho đối tượng (số tham chiếu bằng không).

Trong một số trường hợp, đặc biệt khi sử dụng mẫu RAII, mã kết thúc có thể thực thi mã có thể gây ra lỗi. Tôi tin rằng đây là trường hợp với một số lớp ADODB. Một ví dụ khác là một lớp đóng gói tệp i/o - mã trong Class_Terminate có thể cố gắng xóa và đóng tệp nếu nó vẫn mở, có thể gây ra lỗi. Vì vậy, điều quan trọng cần lưu ý là việc đặt tham chiếu đối tượng thành Không gì có thể gây ra lỗi và xử lý nó (chính xác như thế nào sẽ phụ thuộc vào ứng dụng của bạn - ví dụ bạn có thể bỏ qua các lỗi đó bằng cách chèn "On Error Resume Next" "ngay trước" Đặt ... = Không có gì ").

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