Bagikan melalui


Masa Pakai Objek: Bagaimana Objek Dibuat dan Dihancurkan (Visual Basic)

Instans kelas, objek, dibuat dengan menggunakan New kata kunci. Tugas inisialisasi sering kali harus dilakukan pada objek baru sebelum digunakan. Tugas inisialisasi umum termasuk membuka file, menyambungkan ke database, dan membaca nilai kunci registri. Visual Basic mengontrol inisialisasi objek baru menggunakan prosedur yang disebut konstruktor (metode khusus yang memungkinkan kontrol atas inisialisasi).

Setelah objek meninggalkan cakupan, objek dirilis oleh mesin waktu bahasa umum (CLR). Visual Basic mengontrol rilis sumber daya sistem menggunakan prosedur yang disebut destruktor. Bersama-sama, konstruktor dan destruktor mendukung pembuatan pustaka kelas yang kuat dan dapat diprediksi.

Menggunakan Konstruktor dan Destruktor

Konstruktor dan destruktor mengontrol pembuatan dan penghancuran objek. Prosedur Sub New dan Sub Finalize dalam Visual Basic menginisialisasi dan menghancurkan objek; mereka menggantikan Class_Initialize metode dan Class_Terminate yang digunakan dalam Visual Basic 6.0 dan versi yang lebih lama.

Sub Baru

Sub New Konstruktor hanya dapat berjalan sekali saat kelas dibuat. Ini tidak dapat dipanggil secara eksplisit di mana saja selain di baris pertama kode konstruktor lain dari kelas yang sama atau dari kelas turunan. Selain itu, kode dalam Sub New metode selalu berjalan sebelum kode lain di kelas. Visual Basic secara implisit membuat Sub New konstruktor saat waktu berjalan jika Anda tidak secara eksplisit menentukan Sub New prosedur untuk sebuah kelas.

Untuk membuat konstruktor untuk kelas, buat prosedur bernama Sub New di mana saja dalam definisi kelas. Untuk membuat konstruktor berparameter, tentukan nama dan jenis data argumen Sub New sama seperti yang Anda tentukan argumen untuk prosedur lain, seperti dalam kode berikut:

Sub New(ByVal s As String)

Konstruktor sering kelebihan beban, seperti dalam kode berikut:

Sub New(ByVal s As String, i As Integer)

Ketika Anda menentukan kelas yang berasal dari kelas lain, baris pertama konstruktor harus berupa panggilan ke konstruktor kelas dasar, kecuali kelas dasar memiliki konstruktor yang dapat diakses yang tidak mengambil parameter. Panggilan ke kelas dasar yang berisi konstruktor di atas, misalnya, adalah MyBase.New(s). Jika tidak, MyBase.New bersifat opsional, dan runtime Visual Basic memanggilnya secara implisit.

Setelah Anda menulis kode untuk memanggil konstruktor objek induk, Anda dapat menambahkan kode inisialisasi tambahan ke Sub New prosedur. Sub New dapat menerima argumen ketika dipanggil sebagai konstruktor berparameter. Parameter ini diteruskan dari prosedur yang memanggil konstruktor, misalnya, Dim AnObject As New ThisClass(X).

Sub Finalisasi

Sebelum objek dirilis, CLR secara otomatis memanggil metode Finalize untuk objek yang memiliki prosedur Sub Finalize. Metode Finalize ini dapat berisi kode yang perlu dijalankan tepat sebelum objek dihancurkan, seperti kode untuk menutup file dan menyimpan informasi status. Terdapat sedikit penurunan performa untuk mengeksekusi Sub Finalize, jadi Anda harus menentukan metode Sub Finalize hanya ketika Anda perlu melepaskan objek secara eksplisit.

Nota

Pengumpul sampah di CLR tidak (dan tidak dapat) membuang objek yang tidak dikelola, objek yang dijalankan sistem operasi secara langsung, di luar lingkungan CLR. Ini karena objek yang tidak dikelola yang berbeda harus dibuang dengan cara yang berbeda. Informasi tersebut tidak terkait langsung dengan objek yang tidak dikelola; harus ditemukan dalam dokumentasi untuk objek. Kelas yang menggunakan objek yang tidak terkelola harus menghapusnya dalam metodenya Finalize.

Finalize Destruktor adalah metode terlindungi yang hanya dapat dipanggil dari kelas miliknya, atau dari kelas turunan. Sistem memanggil Finalize secara otomatis ketika objek dihancurkan, jadi Anda tidak boleh secara eksplisit memanggil Finalize dari luar implementasi kelas Finalize turunan.

Tidak seperti Class_Terminate, yang dijalankan segera setelah objek diatur menjadi kosong, biasanya ada penundaan antara saat objek kehilangan lingkup dan ketika Visual Basic memanggil fungsi destruktor Finalize. Visual Basic .NET memungkinkan jenis destruktor kedua, IDisposable.Dispose, yang dapat secara eksplisit dipanggil kapan saja untuk segera merilis sumber daya.

Nota

Finalize Destruktor tidak boleh melemparkan pengecualian, karena tidak dapat ditangani oleh aplikasi dan dapat menyebabkan aplikasi dihentikan.

Cara Kerja Metode Baru dan Finalisasi dalam Hierarki Kelas

Setiap kali instans kelas dibuat, runtime bahasa umum (CLR) mencoba menjalankan prosedur bernama New, jika ada di objek tersebut. New adalah jenis prosedur yang constructor disebut yang digunakan untuk menginisialisasi objek baru sebelum kode lain dalam objek dijalankan. New Konstruktor dapat digunakan untuk membuka file, menyambungkan ke database, menginisialisasi variabel, dan mengurus tugas lain yang perlu dilakukan sebelum objek dapat digunakan.

Ketika instans kelas turunan dibuat, Sub New konstruktor kelas dasar dijalankan terlebih dahulu, diikuti oleh konstruktor di kelas turunan. Ini terjadi karena baris pertama kode dalam Sub New konstruktor menggunakan sintaks MyBase.New()untuk memanggil konstruktor kelas tepat di atas dirinya sendiri dalam hierarki kelas. Konstruktor Sub New dipanggil untuk setiap kelas dalam hierarki kelas hingga mencapai konstruktor kelas dasar. Pada titik itu, kode dalam konstruktor untuk kelas dasar dijalankan, diikuti oleh kode di setiap konstruktor di semua kelas turunan dan kode dalam kelas yang paling turunan dijalankan terakhir.

Cuplikan layar memperlihatkan konstruktor hierarki kelas dan warisan.

Ketika objek tidak lagi diperlukan, CLR memanggil metode untuk objek tersebut Finalize sebelum membebaskan memorinya. Metode Finalize ini disebut destructor karena melakukan tugas pembersihan, seperti menyimpan informasi status, menutup file dan koneksi ke database, dan tugas lain yang harus dilakukan sebelum merilis objek.

Cuplikan layar memperlihatkan destruktor metode Finalize.

Antarmuka IDisposable

Instance kelas sering mengontrol sumber daya yang tidak dikelola oleh CLR, seperti handle Windows dan koneksi database. Sumber daya ini harus dibuang dalam Finalize metode kelas, sehingga mereka akan dilepaskan ketika objek dihancurkan oleh pengumpul sampah. Namun, pengumpul sampah menghancurkan objek hanya ketika CLR membutuhkan lebih banyak memori kosong. Ini berarti bahwa sumber daya mungkin tidak dirilis sampai lama setelah objek keluar dari cakupan.

Untuk melengkapi pengumpulan sampah, kelas Anda dapat menyediakan mekanisme untuk mengelola sumber daya sistem secara aktif jika menerapkan IDisposable antarmuka. IDisposable memiliki satu metode, Dispose, klien mana yang harus memanggil ketika mereka selesai menggunakan objek. Anda dapat menggunakan metode Dispose ini untuk segera merilis sumber daya dan melakukan tugas seperti menutup file dan koneksi database. Finalize Tidak seperti destruktor, Dispose metode ini tidak dipanggil secara otomatis. Klien kelas harus secara eksplisit memanggil Dispose ketika Anda ingin segera merilis sumber daya.

Menerapkan IDisposable

Kelas yang mengimplementasikan IDisposable antarmuka harus menyertakan bagian kode ini:

  • Bidang untuk melacak apakah objek telah dibuang:

    Protected disposed As Boolean = False
    
  • Kelebihan beban Dispose yang membebaskan sumber daya kelas. Metode ini harus dipanggil oleh metode Dispose dan Finalize dari kelas dasar:

    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposed Then
            If disposing Then
                ' Insert code to free managed resources.
            End If
            ' Insert code to free unmanaged resources.
        End If
        Me.disposed = True
    End Sub
    
  • Implementasi Dispose yang hanya berisi kode berikut:

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
    
  • Metode Finalize yang ditindih hanya berisi kode berikut:

    Protected Overrides Sub Finalize()
        Dispose(False)
        MyBase.Finalize()
    End Sub
    

Berasal dari Kelas yang Menerapkan IDisposable

Kelas yang berasal dari kelas dasar yang mengimplementasikan IDisposable antarmuka tidak perlu mengambil alih salah satu metode dasar kecuali menggunakan sumber daya tambahan yang perlu dibuang. Dalam situasi itu, kelas turunan harus mengambil alih metode kelas Dispose(disposing) dasar untuk membuang sumber daya kelas turunan. Penimpaan ini harus memanggil metode kelas Dispose(disposing) dasar.

Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    If Not Me.disposed Then
        If disposing Then
            ' Insert code to free managed resources.
        End If
        ' Insert code to free unmanaged resources.
    End If
    MyBase.Dispose(disposing)
End Sub

Kelas turunan tidak boleh menimpa metode kelas dasar Dispose dan Finalize. Ketika metode tersebut dipanggil dari instans kelas turunan, implementasi metode dari kelas dasar akan memanggil penimpaan metode dari kelas turunan Dispose(disposing).

Pengumpulan Sampah dan Finalisasi Destructor

.NET Framework menggunakan sistem pengumpulan sampah dengan pelacakan referensi untuk secara berkala melepaskan sumber daya yang tidak digunakan. Visual Basic 6.0 dan versi yang lebih lama menggunakan sistem lain yang disebut penghitungan referensi untuk mengelola sumber daya. Meskipun kedua sistem melakukan fungsi yang sama secara otomatis, ada beberapa perbedaan penting.

CLR secara berkala menghancurkan objek ketika sistem menentukan bahwa objek tersebut tidak lagi diperlukan. Objek dirilis lebih cepat ketika sumber daya sistem terbatas, dan lebih jarang jika tidak. Penundaan antara ketika objek kehilangan cakupan dan ketika CLR melepaskannya berarti bahwa, tidak seperti objek di Visual Basic 6.0 dan versi sebelumnya, Anda tidak dapat menentukan dengan tepat kapan objek akan dihancurkan. Dalam situasi seperti itu, objek dikatakan memiliki masa pakai non-deterministik. Dalam kebanyakan kasus, masa pakai non-deterministik tidak mengubah cara Anda menulis aplikasi, selama Anda ingat bahwa Finalize destruktor mungkin tidak segera dijalankan ketika objek kehilangan cakupan.

Perbedaan lain antara sistem pengumpulan sampah melibatkan penggunaan Nothing. Untuk memanfaatkan penghitungan referensi di Visual Basic 6.0 dan versi yang lebih lama, pemrogram terkadang ditetapkan Nothing ke variabel objek untuk merilis referensi yang disimpan variabel tersebut. Jika variabel memegang referensi terakhir ke objek, sumber daya objek akan segera dirilis. Dalam versi Visual Basic yang lebih baru, meskipun mungkin ada kasus di mana prosedur ini masih berharga, melakukannya tidak pernah menyebabkan objek yang dirujuk melepaskan sumber dayanya secepatnya. Untuk segera merilis sumber daya, gunakan metode objek Dispose , jika tersedia. Satu-satunya waktu Anda harus mengatur variabel Nothing adalah ketika masa pakainya relatif lama terhadap waktu yang dibutuhkan pengumpul sampah untuk mendeteksi objek tanpa intim.

Lihat juga