Class — adalah tipe referensi (reference type) dalam bahasa Swift, yang instansnya dikirim melalui referensi, bukan disalin saat penugasan. Berbeda dengan struktur, kelas mendukung pewarisan, deinisialisasi dan penghitungan referensi otomatis ARC untuk manajemen memori. Menurut Swift Programming Language Guide, 2026, class diperlukan untuk bekerja dengan framework UI Apple (UIKit, AppKit) dan implementasi pola yang memerlukan identitas bersama objek. Pilihan antara class dan struct adalah salah satu keputusan arsitektural kunci di Swift.
Poin utama
Class (kelas) — adalah tipe referensi gabungan di Swift yang mengelompokkan properti dan metode menjadi satu entitas dengan dukungan pewarisan dan pengiriman dinamis. Berbeda dengan struct, instans kelas dibuat di heap, dan variabel menyimpan referensi ke instans ini, bukan data itu sendiri.
Ketika Anda menetapkan variabel kelas ke variabel lain, keduanya merujuk ke objek yang sama di memori. Perubahan melalui satu referensi terlihat melalui referensi lainnya — ini adalah properti fundamental dari reference types, yang digunakan dalam pola delegasi, observasi, dan keadaan bersama.
Menurut Apple Swift Documentation, kelas adalah satu-satunya cara untuk bekerja dengan UIKit dan AppKit, di mana semua komponen UI mewarisi dari UIView dan UIViewController. Selain itu, kelas diperlukan untuk mengimplementasikan pola yang memerlukan identitas objek (dua referensi ke satu objek) dan masa hidup yang terkontrol.
Semantik reference type — properti kunci dari kelas. Saat menetapkan kelas ke variabel baru, Swift menyalin referensi, bukan data. Semua variabel yang merujuk ke instans yang sama melihat keadaan saat ini dan dapat mengubahnya. Perilaku ini pada dasarnya berbeda dari value types, di mana setiap variabel menerima salinan independen.
// Contoh semantik reference type
class User {
var name: String
init(name: String) { self.name = name }
}
let user1 = User(name: "Alice")
let user2 = user1 // user2 — referensi yang sama
user2.name = "Bob"
print(user1.name) // "Bob" — diubah melalui user2!
// Pemeriksaan identitas dengan operator ===
print(user1 === user2) // true — objek yang sama
Operator === (identitas) dan !== memeriksa apakah dua variabel merujuk ke instans kelas yang sama. Ini berbeda dari == (kesetaraan), yang membandingkan nilai properti. Untuk struct operator === tidak tersedia — value types tidak memiliki identitas.
Pewarisan — mekanisme di mana kelas dapat mengambil alih properti dan metode dari kelas induk. Di Swift sebuah kelas hanya dapat mewarisi dari satu induk (single inheritance), tetapi dapat mengimplementasikan banyak protokol. Kata kunci override memungkinkan untuk menimpa metode atau properti yang diwarisi.
Setiap kelas yang tidak mewarisi dari kelas lain secara otomatis menjadi kelas dasar (jangan disamakan dengan NSObject). Subkelas menunjukkan induk dengan titik dua setelah nama. Jika subkelas menimpa metode induk, ia harus memanggil super.metode() untuk mempertahankan perilaku induk — ini adalah persyaratan kompiler.
Kata kunci final sebelum class melarang pewarisan. Kompiler dapat mengoptimalkan panggilan metode dari kelas final melalui static dispatch, yang meningkatkan kinerja. Gunakan final untuk kelas yang tidak dimaksudkan untuk diperluas — ini mendokumentasikan niat Anda dan mempercepat kode.
// Contoh pewarisan kelas di Swift
class Vehicle {
var speed: Double = 0
func description() -> String {
"Speed: \(speed) km/h"
}
}
// Car mewarisi Vehicle
class Car: Vehicle {
var brand: String = "Unknown"
override func description() -> String {
"\(brand) - \(speed) km/h"
}
}
// Final class — mencegah pewarisan
final class ElectricCar: Car {
var batteryLevel: Double = 100
}
let tesla = ElectricCar()
tesla.brand = "Tesla"
tesla.speed = 120
print(tesla.description()) // "Tesla - 120.0 km/h"
Pewarisan kelas adalah mekanisme yang kuat namun bertanggung jawab. Hirarki yang dalam (5+ tingkat) mempersulit pemeliharaan dan pengujian. Untuk penggunaan kembali fungsionalitas tanpa pewarisan, gunakan protokol dengan extension dan pemrograman berorientasi protokol — pendekatan yang Apple promosikan sebagai alternatif untuk hirarki kelas yang dalam.
Swift menggunakan ARC (Automatic Reference Counting) untuk manajemen memori kelas. Setiap instans kelas memiliki penghitung referensi kuat. Saat membuat referensi kuat baru, penghitung meningkat; saat dihancurkan — menurun. Ketika penghitung mencapai nol, memori dibebaskan.
Deinit — metode yang dipanggil secara otomatis sebelum pembebasan instans kelas. Di dalamnya sumber daya dibebaskan: file ditutup, berhenti berlangganan notifikasi, timer dihentikan. Deinit hanya ada di kelas — struktur dan enumerasi tidak memilikinya.
Untuk mencegah siklus referensi kuat (retain cycles), Swift menyediakan referensi weak dan unowned. Weak — referensi opsional yang secara otomatis menjadi nil saat objek dibebaskan. Unowned — non-opsional, tetapi merujuk ke objek yang dijamin hidup lebih lama dari konteks saat ini. Retain cycle tipikal muncul dalam relasi parent-child: child menyimpan referensi kuat ke parent.
// Contoh ARC dan referensi weak
class Parent {
var name: String
var child: Child?
init(name: String) { self.name = name }
deinit { print("\(name) didealokasi") }
}
class Child {
var name: String
weak var parent: Parent? // weak mencegah retain cycle
init(name: String) { self.name = name }
deinit { print("\(name) didealokasi") }
}
var parent: Parent? = Parent(name: "Anna")
parent?.child = Child(name: "Mia")
parent?.child?.parent = parent
parent = nil // Kedua objek didealokasi!
// Tanpa weak akan membuat retain cycle
Selalu gunakan weak untuk referensi dari objek anak ke induk dan untuk daftar tangkapan di closure. Gunakan unowned hanya ketika Anda yakin objek akan bertahan dari konteks saat ini — penggunaan unowned yang salah dapat menyebabkan crash saat mengakses memori yang telah dibebaskan.
Pilihan antara class dan struct adalah keputusan arsitektural yang mempengaruhi kinerja, keamanan thread, dan desain API. Mari kita lihat tabel perbedaan kunci yang akan membantu mengambil keputusan yang tepat dalam setiap kasus konkret.
| Karakteristik | class | struct |
|---|---|---|
| Tipe | Reference type (referensi) | Value type (salinan) |
| Memori | Heap + ARC | Stack / inline |
| Pewarisan | Mendukung (satu induk) | Tidak mendukung |
| Deinit | Ada | Tidak ada |
| Identitas (===) | Mendukung | Tidak mendukung |
| Mutating | Tidak diperlukan (selalu mutating) | Hanya dengan mutating |
| Memberwise init | Tidak dihasilkan | Dihasilkan otomatis |
| Keamanan thread | Tidak dijamin (keadaan bersama) | Dijamin (penyalinan) |
Gunakan kelas ketika Anda membutuhkan identitas bersama (beberapa bagian kode bekerja dengan satu objek), pewarisan atau interaksi dengan Objective-C runtime. Untuk semua hal lainnya, struktur lebih disukai — lebih cepat, lebih aman dalam kode multi-thread dan tidak memerlukan manajemen memori.
Meskipun rekomendasi Apple untuk menggunakan struct secara default, kelas diperlukan dalam beberapa skenario konkret. Mari kita bahas masing-masing dengan contoh praktis.
Semua komponen UI di iOS dan macOS adalah kelas yang mewarisi dari UIView (iOS) atau NSView (macOS). Anda tidak dapat mengganti UIViewController dengan struktur — ia memerlukan pewarisan dan deinit untuk membebaskan sumber daya. Saat bekerja dengan UIKit, gunakan kelas untuk controller, view, dan delegate mereka.
Pola Singleton (satu instans kelas untuk seluruh aplikasi) memerlukan semantik referensial. Manager: NetworkManager, SettingsManager, AnalyticsService — biasanya diimplementasikan sebagai kelas dengan shared static property. Struktur tidak cocok karena setiap salinan akan menjadi instans independen.
Ketika sebuah objek harus menjadi sumber kebenaran tunggal (single source of truth) dan dikirim antar modul melalui referensi — gunakan class. Ini berkaitan dengan manajemen keadaan di mana perubahan objek di satu tempat harus terlihat di semua komponen yang bergantung. Untuk ObservableObject di SwiftUI, kelas wajib digunakan.
// ObservableObject — class diperlukan untuk SwiftUI
import SwiftUI
class AppViewModel: ObservableObject {
@Published var isLoggedIn: Bool = false
@Published var username: String = ""
func login(user: String) {
isLoggedIn = true
username = user
}
}
// Penggunaan di SwiftUI View
struct ContentView: View {
@StateObject var viewModel = AppViewModel()
var body: some View {
Text(viewModel.isLoggedIn ? "Selamat datang" : "Masuk")
}
}
Aturan: jika objek harus memiliki identitas (dua referensi -> satu objek), menjadi instans unik atau bekerja dengan UIKit/Objective-C — pilih class. Jika objek hanya menyimpan data — pilih struct.
Pertanyaan yang sering diajukan
Class — adalah tipe referensi (reference type) di Swift yang mendukung pewarisan, deinisialisasi dan ARC untuk manajemen memori. Instans kelas disimpan di heap, dan variabel berisi referensi ke objek, bukan salinannya.
Class — reference type (dikirim melalui referensi), mendukung pewarisan dan deinit. Struct — value type (disalin), tidak mendukung pewarisan, tetapi mengimplementasikan protokol dan mendapatkan memberwise init secara otomatis. Swift merekomendasikan struct sebagai tipe default.
ARC (Automatic Reference Counting) — mekanisme manajemen memori untuk kelas Swift. Setiap instans memiliki penghitung referensi kuat. Ketika penghitung mencapai nol, memori dibebaskan. Referensi weak dan unowned mencegah retain cycles antar objek.
Deinit — metode kelas yang dipanggil secara otomatis sebelum pembebasan memorinya. Digunakan untuk menutup file, berhenti berlangganan notifikasi dan operasi penyelesaian lainnya. Deinit hanya ada di kelas — struktur tidak memilikinya.
Gunakan class untuk komponen UI UIKit/AppKit, singleton, ObservableObject di SwiftUI, objek dengan identitas bersama (delegate, observer) dan saat bekerja dengan Objective-C runtime. Untuk model data, DTO dan konfigurasi, struct lebih disukai.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga