Czy istnieje potrzeba ustawiania obiektów na nic wewnątrz funkcji VBA

Zawsze czytam, że zaleca się ustawianie obiektów na nic, gdy już z nimi skończę. Ale zwykle używam ich tylko w funkcjach wewnątrz form.

Czy odniesienie nie jest utracone i pamięć zwolniona, gdy zakres funkcji zostanie pozostawiony, niezależnie od ustawienia obiektów na nic?

Tzn. czy naprawdę trzeba to zrobić:

Set db = Nothing
Set record_set = Nothing
Author: shruti1810, 2009-02-05

7 answers

VB używa tzw." zliczania referencji".

Zasadniczo, w momencie gdy zmienna wychodzi poza zakres, licznik odniesienia na obiekcie odniesienia jest zmniejszany. Po przypisaniu odniesienia do obiektu do innej zmiennej licznik odniesienia jest zwiększany.

Gdy licznik osiągnie zero, obiekt jest gotowy do zbierania śmieci. Zasoby obiektu zostaną zwolnione, gdy tylko to nastąpi. Zmienna lokalna funkcji najprawdopodobniej odwoła się do obiekt, którego liczba referencji nigdy nie przekracza 1, więc zasoby obiektu zostaną zwolnione po zakończeniu funkcji.

Ustawienie zmiennej na {[0] } jest sposobem jawnego zmniejszenia licznika referencji.

Na przykład, odczytujesz plik i ustawiasz zmienną obiektu file na Nothing zaraz po wywołaniu ReadAll(). Uchwyt pliku zostanie zwolniony natychmiast, możesz poświęcić czas na przetworzenie jego zawartości.

Jeśli nie ustawisz na Nothing, uchwyt pliku może być otwarty dłużej niż to absolutnie konieczne.

Jeśli nie jesteś w sytuacji" musisz odblokować cenne zasoby", po prostu pozwolić zmiennym wyjść poza zakres jest w porządku.

 65
Author: Tomalak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-05 06:44:04

Wywóz śmieci rzadko jest doskonały. Nawet w. NET zdarzają się sytuacje, w których zaleca się, aby system wcześnie zaczął usuwać śmieci.

Z tego powodu jawnie zamykam i ustawiam na Nothing recordsets, kiedy z nimi skończę.

 13
Author: BIBD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-05 18:16:42

Ostatnia linijka tematu Pomocy dla " Recordset.Close " w Microsoft DAO help I Access Developer Reference jest następujący:

" alternatywą dla metody Close jest aby ustawić wartość zmiennej obiektowej Do Nothing(Set dbsTemp = Nothing)."

Http://msdn.microsoft.com/en-us/library/bb243098.aspx

Mając to na uwadze, Ten artykuł Z Bazy wiedzy Microsoft zatytułowany " Jak zapobiec nadmuchaniu bazy danych po you use Data Access Objects (DAO)", mówi, że należy jawnie zamknąć, jeśli nie chcesz, aby Twoje bazy danych bloat. Zauważysz, że artykuł jest trochę niejasny co do szczegółów; sekcja" przyczyna " jest niejasna, prawie do tego stopnia, że jest bełkot.

Http://support.microsoft.com/kb/289562

Objawy: baza danych Microsoft Access zaczął wzdęcia (lub szybko rosnąć w rozmiar) po zaimplementowaniu dostępu do danych Obiektów (DAO), aby otworzyć zestaw rekordów.

CAUSE: If you do not release a pamięć rekordów za każdym razem, gdy ty loop through the recordset code, DAO może przekompilować, wykorzystując więcej pamięci i zwiększenie rozmiaru bazy danych.

Więcej informacji: podczas tworzenia Recordset (lub QueryDef) obiekt w kodu, jawnie zamknąć Obiekt, gdy jesteś skończony. Microsoft Access automatycznie zamyka zestaw rekordów i QueryDef obiekty pod najbardziej okoliczności. Jednakże, jeśli jawnie Zamknij obiekt w Twoim kod, można uniknąć okazjonalnych przypadki, gdy obiekt pozostaje otwórz.

Na koniec dodam, że pracuję z bazami danych Access od 15 lat i prawie zawsze pozwalam, aby moje lokalnie zadeklarowane zmienne zestawu rekordów wyszły poza zakres bez jawnego użycia metody Close. Nie zrobiłem żadnych testów na nim, ale to nie wydaje się mieć znaczenia.

 10
Author: Shane Miskin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-05 23:39:35

Odniesienia powinny być oczyszczone, gdy zmienna wykracza poza zakres. Prawdopodobnie poprawiło się to wraz z późniejszymi wersjami oprogramowania, ale w pewnym momencie nie było to wiarygodne. Uważam, że dobrą praktyką pozostaje jednoznaczne ustawienie zmiennych na "nic"."

 2
Author: John Mo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-05 17:57:14

Gdy używasz ASP classic( skrypty po stronie serwera), importuje się, aby ustawić wszystkie obiekty na nic po ich zakończeniu, ponieważ nie wychodzą one poza zakres, dopóki serwer [wirtualny] nie zostanie zamknięty.

Z tego powodu wszystkie przykłady skryptów MS VB zawsze pokazywały obiekty zamknięte i ustawione na nic. Aby fragmenty skryptu mogły być używane w środowiskach takich jak ASP classic, gdzie obiekty nie wyszły poza zasięg.

Są, rzadko, inne sytuacje, w których chcesz zakodować długo działające procesy, w których obiekty nie wychodzą poza zakres, a kończy ci się pamięć fizyczna, jeśli nie zwolnisz jawnie obiektów.

Jeśli uważasz, że kodujesz ASP classic lub uruchamiasz procesy w zasięgu globalnym z jakiegoś innego powodu, to tak, powinieneś jawnie zwolnić obiekty.

 2
Author: david,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-17 10:31:10

Zazwyczaj zawsze umieszczam to na końcu moich procedur, lub wywołuję sub "CloseRecordSet" z nim, Jeśli używam tych z poziomu modułów:

Private Sub Rawr()
On Error GoTo ErrorHandler

    'Procedural Code Here.

    ExitPoint:
        'Closes and Destroys RecordSet Objects.
        If Not Recset Is Nothing Then
            If Recset.State = 1 Then
                Recset.Close
                Conn.Close
            End If
            Set Recset = Nothing
            Set Conn = Nothing
        End If
        Exit Sub

    ErrorHandler:
        'Error Handling / Reporting Here.
        Resume ExitPoint
End Sub

W ten sposób procedura się kończy, (czy to normalnie, czy z powodu błędu) obiekty są czyszczone, a zasoby są wolne.

Robienie tego w ten sposób jest całkiem bezpieczne, ponieważ można go po prostu wcisnąć i zrobi tylko to, co jest konieczne w odniesieniu do zamknięcia lub zniszczenia obiektu recordset / connection, okaż, że już został zamknięte (z powodu błędu runtime lub po prostu zamknięcie go wcześniej, jak powinieneś, to po prostu upewnia się).

To naprawdę nie wiele kłopotów i zawsze najlepiej jest wyczyścić obiekty, gdy skończysz z nimi, aby natychmiast zwolnić zasoby, niezależnie od tego, co dzieje się w programie.

 1
Author: BobT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-26 15:15:50

Spróbuj tego

If Not IsEmpty(vMyVariant) Then
    Erase vMyVariant
    vMyVariant = Empty
End If
 0
Author: user2006617,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 07:51:17