Kekhususan Swift dalam pengembangan seluler: apa itu, fitur utama dan cara kerjanya

Penulis: IT Sectr Diterbitkan: 2026-06-25 Waktu membaca: 17 mnt

Swift adalah bahasa pemrograman Apple yang menggabungkan kekuatan Objective-C dengan keamanan bahasa modern. Tidak seperti banyak bahasa lainnya, Swift menawarkan konstruksi unik: tipe nilai dengan penyalinan otomatis, Actor dengan isolasi tingkat kompiler, Property Wrappers untuk menggunakan kembali logika properti, dan Pemrograman Berorientasi Protokol sebagai alternatif pewarisan klasik. Menurut Dokumentasi Apple Swift, fitur-fitur ini membuat kode lebih aman dan efisien.

Poin Penting

  • Struct — tipe nilai, disalin saat penugasan, tidak mendukung pewarisan. Class — tipe referensi, diteruskan oleh referensi, mendukung pewarisan dan deinit.
  • Actor — tipe referensi thread-safe dengan isolasi tingkat kompiler. Kompiler mencegah akses bersamaan ke status yang dapat diubah dari tugas yang berbeda.
  • Property Wrappers — @Published, @State, @Binding merangkum logika properti di SwiftUI dan Combine, menghilangkan kode boilerplate.
  • Generics memungkinkan penulisan fungsi dan struktur type-safe tanpa terikat pada tipe tertentu. Pemrograman Berorientasi Protokol menggunakan extension + protocol, bukan hierarki kelas.
  • Enum dengan nilai terkait — alat yang ampuh untuk memodelkan status. Setiap kasus dapat menyimpan kumpulan data arbitrer dari berbagai tipe.

Struct vs Class di Swift: tipe nilai dan tipe referensi

Di Swift, struct adalah tipe nilai, sedangkan class adalah tipe referensi. Perbedaan mendasar ini menentukan perilaku selama penugasan, penerusan ke fungsi, dan manajemen memori. Struct disalin seluruhnya pada setiap penugasan, class diteruskan oleh referensi — hanya penunjuk ke objek heap yang disalin.

Semantik Nilai Struct

Struct secara otomatis menerapkan semantik nilai — setiap instance independen. Mutasi properti struct hanya mungkin melalui var, dan metode yang mengubah properti harus ditandai sebagai mutating. Struct tidak mendukung pewarisan tetapi dapat sesuai dengan protokol. Pustaka standar Swift menggunakan struct untuk String, Array, Dictionary, Int, Bool — semua tipe fundamental adalah tipe nilai.

swift
struct User {
    let id: Int
    var name: String

    mutating func updateName(_ newName: String) {
        name = newName
    }
}

var user1 = User(id: 1, name: "Alice")
var user2 = user1
user2.updateName("Bob")
// user1.name === "Alice", user2.name === "Bob"
// Salinan lengkap — instance independen

Semantik Referensi Class

Class disimpan di heap dan mendukung kesetaraan referensi. Beberapa variabel dapat mereferensi objek yang sama, perubahan melalui satu referensi terlihat melalui semua referensi lainnya. Class mendukung pewarisan, memungkinkan penggantian metode (override), memiliki deinit untuk pembersihan sumber daya. Di Swift, class lebih jarang digunakan daripada struct — Apple merekomendasikan memulai dengan struct dan beralih ke class hanya ketika pewarisan atau semantik referensi diperlukan.

swift
class Car {
    let model: String
    var speed: Int

    init(model: String, speed: Int) {
        self.model = model
        self.speed = speed
    }

    func accelerate(_ amount: Int) {
        speed += amount
    }
}

let car1 = Car(model: "Tesla", speed: 0)
let car2 = car1
car2.accelerate(50)
// car1.speed === 50, car2.speed === 50
// Referensi yang sama — perubahan terlihat di mana-mana

Pilihan antara struct dan class tergantung pada semantik data. Untuk konfigurasi, model data, dan status gunakan struct — penyalinan lebih aman dan dapat diprediksi. Untuk objek dengan identitas (sesi pengguna, koneksi database) dan ketika pewarisan diperlukan, gunakan class.

Actor — keamanan thread di Swift

Actor adalah tipe referensi yang melindungi status yang dapat diubah dari akses bersamaan. Kompiler Swift menjamin bahwa variabel actor hanya dapat diakses dari konteks actor yang sama — akses eksternal apa pun menyebabkan kesalahan kompilasi. Ini mencegah perlombaan data di tingkat bahasa, tanpa kunci manual.

Isolasi Actor

Semua properti dan metode actor diisolasi secara default. Memanggil metode actor dari luar memerlukan await — Swift mengalihkan eksekusi ke actor dan kembali. Actor menyinkronkan akses secara berurutan: permintaan dari tugas yang berbeda diantrekan. Ini menjamin status yang konsisten di dalam actor. Metode yang tidak terisolasi (nonisolated) dapat dipanggil tanpa await tetapi tidak dapat mengakses properti yang dapat diubah.

swift
actor BankAccount {
    private var balance: Double

    init(initialBalance: Double) {
        balance = initialBalance
    }

    func deposit(amount: Double) {
        balance += amount
    }

    func withdraw(amount: Double) throws {
        guard balance >= amount else {
            throw BankError.insufficientFunds
        }
        balance -= amount
    }

    nonisolated func accountInfo() -> String {
        return "Rekening Bank"
    }
}

let account = BankAccount(initialBalance: 1000)
await account.deposit(amount: 500)
// balance = 1500 — atomik, tanpa kondisi balapan

Actor berguna untuk manajer status, cache, dan layanan jaringan di mana beberapa tugas membaca dan menulis data secara bersamaan. Tidak seperti sinkronisasi manual melalui NSLock atau DispatchQueue, actor diperiksa pada waktu kompilasi — tidak mungkin membuat kesalahan. Kesalahan isolasi muncul pada waktu kompilasi, bukan waktu proses.

Property Wrappers: @Published, @State, @Binding

Property Wrapper adalah anotasi yang menambahkan perilaku ke properti tanpa mengubah deklarasinya. SwiftUI dan Combine menyediakan pembungkus bawaan untuk mengelola status tampilan. Kompiler menghasilkan kode yang membungkus akses properti, menambahkan logika observasi, sinkronisasi, atau transformasi.

@Published dan @State

@Published digunakan di kelas yang sesuai dengan ObservableObject untuk mempublikasikan perubahan secara otomatis. Pelanggan Combine menerima notifikasi pada setiap pembaruan. @State adalah status lokal tampilan SwiftUI. SwiftUI secara otomatis menggambar ulang tampilan saat @State berubah. @Binding membuat koneksi dua arah antara tampilan induk dan anak tanpa memiliki data.

swift
import SwiftUI
import Combine

@main
struct CounterApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class CounterViewModel: ObservableObject {
    @Published var count: Int = 0

    func increment() {
        count += 1
    }
}

struct ContentView: View {
    @State private var greeting: String = "Halo"
    @StateObject private var viewModel = CounterViewModel()

    var body: some View {
        VStack {
            CounterDisplay(count: $viewModel.count)
            Text(greeting)
            Button("Tambah", action: viewModel.increment)
        }
    }
}

struct CounterDisplay: View {
    @Binding var count: Int

    var body: some View {
        Text("Hitungan: \(count)")
    }
}

Property Wrappers khusus dibuat menggunakan @propertyWrapper dan struktur dengan bidang wrappedValue. Ini memungkinkan penggunaan kembali logika: validasi, normalisasi, penyimpanan UserDefaults. Property Wrappers secara signifikan mengurangi kode boilerplate dan membuat niat pengembang eksplisit melalui anotasi.

swift
@propertyWrapper
struct Clamped<T: Comparable> {
    private var value: T
    let range: ClosedRange<T>

    init(wrappedValue: T, range: ClosedRange<T>) {
        self.range = range
        self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }

    var wrappedValue: T {
        get { value }
        set { value = min(max(newValue, range.lowerBound), range.upperBound) }
    }
}

struct Settings {
    @Clamped(range: 0...100) var volume: Int = 50
}

var s = Settings()
s.volume = 150
// s.volume === 100 — nilai otomatis dibatasi

Generics dan Pemrograman Berorientasi Protokol

Generics adalah mekanisme Swift yang kuat untuk menulis kode fleksibel tanpa kehilangan keamanan tipe. Fungsi dan tipe generik bekerja dengan tipe apa pun yang memenuhi batasan. Pemrograman Berorientasi Protokol (POP) adalah paradigma Swift di mana protocol + extension menggantikan pewarisan kelas klasik, menyediakan komposisi perilaku.

Batasan Generik dan Tipe Terkait

Swift memungkinkan membatasi parameter generik dengan protokol (klausa where). Protokol dengan tipe terkait adalah padanan generik untuk protokol: tipe konkret ditentukan pada saat kesesuaian. Ini adalah dasar untuk koleksi dan algoritma type-safe. Pustaka standar Swift secara aktif menggunakan Generics: Array, Dictionary, Optional — semuanya adalah tipe generik.

swift
protocol Cacheable {
    associatedtype Key: Hashable
    associatedtype Value

    func get(_ key: Key) -> Value?
    mutating func set(_ value: Value, for key: Key)
}

struct MemoryCache<K: Hashable, V>: Cacheable {
    private var storage: [K: V] = [:]

    typealias Key = K
    typealias Value = V

    func get(_ key: K) -> V? {
        return storage[key]
    }

    mutating func set(_ value: V, for key: K) {
        storage[key] = value
    }
}

func firstMatch<T: Equatable>(in array: [T], target: T) -> Int? {
    for (index, item) in array.enumerated() {
        if item == target {
            return index
        }
    }
    return nil
}

let numbers = [10, 20, 30, 40]
let index = firstMatch(in: numbers, target: 30)
// index === 2 — satu metode generik untuk semua tipe Equatable

Extension Protokol dan Implementasi Default

Extension protokol adalah mekanisme kunci POP. Dalam extension, implementasi default metode protokol dapat disediakan. Tipe yang sesuai dengan protokol mendapatkan implementasi ini secara gratis dan dapat menimpanya jika diperlukan. Ini memungkinkan pembangunan hierarki perilaku tanpa pewarisan kelas — alternatif untuk pewarisan berganda, yang tidak ada di Swift.

swift
protocol Drivable {
    var speed: Double { get set }
    func drive()
}

extension Drivable {
    func drive() {
        if speed > 0 {
            print("Mengemudi dengan kecepatan \(speed) km/jam")
        }
    }
}

struct Bicycle: Drivable {
    var speed: Double = 15
}

struct Plane: Drivable {
    var speed: Double = 900

    func drive() {
        print("Terbang dengan kecepatan \(speed) km/jam")
    }
}

let bike = Bicycle()
bike.drive() // "Mengemudi dengan kecepatan 15.0 km/jam" — default

let plane = Plane()
plane.drive() // "Terbang dengan kecepatan 900.0 km/jam" — ditimpa

POP dengan extension memungkinkan komposisi melalui beberapa protokol — sebuah tipe dapat sesuai dengan beberapa protokol, mendapatkan implementasinya. Ini lebih fleksibel daripada pewarisan kelas tunggal di mana seluruh hierarki tetap. Pustaka standar Swift dibangun di atas POP: CustomStringConvertible, Equatable, Hashable, Codable — semuanya adalah protokol dengan extension.

Enum dengan nilai terkait dan Extension

Enum di Swift adalah konstruksi yang jauh lebih kuat daripada di bahasa lain. Setiap kasus dapat memiliki nilai terkait — kumpulan data arbitrer dari tipe apa pun. Dikombinasikan dengan extension dan pencocokan pola, enum menjadi dasar untuk memodelkan status, hasil operasi, dan mesin status terbatas.

Nilai Terkait dan Pencocokan Pola

Nilai terkait memungkinkan setiap kasus menyimpan data unik. Misalnya, kasus loading tidak mengandung data, success mengandung hasil, failure mengandung kesalahan. Pencocokan pola melalui switch mengekstrak nilai terkait dan memproses setiap kasus. Kompiler memeriksa kelengkapan (exhaustive switch) — ini menghilangkan status yang terlupakan.

swift
enum NetworkResult<T> {
    case loading
    case success(T)
    case failure(Error)
}

enum MediaFile {
    case image(url: URL, width: Int, height: Int)
    case video(url: URL, duration: Double)
    case audio(url: URL, bitrate: Int)
}

func handle(_ result: NetworkResult<String>) {
    switch result {
    case .loading:
        print("Memuat...")
    case .success(let data):
        print("Diterima: \(data)")
    case .failure(let error):
        print("Kesalahan: \(error.localizedDescription)")
    }
}

let file = MediaFile.video(url: URL(string: "https://example.com/video.mp4")!, duration: 120)

if case .video(let url, let duration) = file {
    print("Video \(url) durasi \(duration)s")
}

Extension untuk Enum

Swift memungkinkan penambahan metode, properti terhitung, dan kesesuaian protokol melalui extension untuk enum. Ini tidak memerlukan perubahan deklarasi asli — kode tetap bersih dan modular. Metode dalam extension dapat bekerja dengan nilai terkait, menghitung data turunan, dan menerapkan logika bisnis.

swift
extension MediaFile {
    var fileName: String {
        switch self {
        case .image(let url, _, _),
             .video(let url, _),
             .audio(let url, _):
            return url.lastPathComponent
        }
    }

    var description: String {
        switch self {
        case .image(_, let w, let h):
            return "Gambar \(w)x\(h)"
        case .video(_, let d):
            return "Video \(d)s"
        case .audio(_, let b):
            return "Audio \(b) kbps"
        }
    }
}

extension MediaFile: Equatable {
    static func == (lhs: MediaFile, rhs: MediaFile) -> Bool {
        return lhs.fileName == rhs.fileName
    }
}

let files: [MediaFile] = [file]
files.forEach { print($0.description) }
// "Video 120.0s"

Enum dengan nilai terkait + extension adalah pengganti untuk kelas tersegel dari Kotlin atau union yang didiskriminasi dari bahasa lain. Swift menggunakan kombinasi ini untuk Result (tipe standar di pustaka standar), Optional (Optional adalah enum dengan .none dan .some) dan penanganan status di SwiftUI. Pencocokan pola menjamin semua status ditangani — kesalahan waktu proses tidak mungkin terjadi.

Pertanyaan yang Sering Diajukan

Bagaimana struct berbeda dari class di Swift?

Struct — tipe nilai, disalin saat penugasan, tidak mendukung pewarisan. Class — tipe referensi, diteruskan oleh referensi, mendukung pewarisan, deinit dan pemeriksaan identitas (===). Apple merekomendasikan memulai dengan struct dan beralih ke class hanya ketika semantik referensi diperlukan.

Apa itu Actor di Swift dan kapan menggunakannya?

Actor — tipe referensi thread-safe. Kompiler mencegah akses bersamaan ke status yang dapat diubah dari konteks yang berbeda. Gunakan Actor untuk manajer status, cache, dan layanan yang diakses oleh beberapa tugas. Memanggil metode actor memerlukan await.

Property Wrappers apa yang digunakan di SwiftUI?

Utama: @State — status tampilan lokal; @Binding — koneksi data tanpa kepemilikan; @Published — publikasi perubahan di ObservableObject; @StateObject — kepemilikan ObservableObject; @EnvironmentObject — ketergantungan dari lingkungan. Pembungkus khusus dibuat melalui @propertyWrapper.

Apa itu Pemrograman Berorientasi Protokol?

POP — paradigma di mana protocol + extension mendefinisikan perilaku, bukan pewarisan kelas. Sebuah tipe sesuai dengan beberapa protokol, mendapatkan implementasinya secara gratis. Ini adalah komposisi daripada pewarisan — lebih fleksibel dan aman. Pustaka standar Swift (Equatable, Codable) dibangun di atas POP.

Bagaimana enum di Swift berbeda dari enum di bahasa lain?

Enum di Swift mendukung nilai terkait — setiap kasus dapat menyimpan data arbitrer dari berbagai tipe. Dikombinasikan dengan pencocokan pola (switch), ini memberikan model yang kuat untuk status, kesalahan, dan Domain-Driven Design. Optional dan Result adalah enum Swift standar dengan nilai terkait.

Ringkasan

  • Struct vs Class — perbedaan mendasar: tipe nilai disalin, tipe referensi diteruskan oleh referensi. Struct tidak mendukung pewarisan, class mendukung. Apple merekomendasikan struct secara default.
  • Actor — keamanan thread tingkat kompiler. Status yang dapat diubah terisolasi, akses melalui await, perlindungan dari perlombaan data tanpa kunci manual.
  • Property Wrappers — @Published, @State, @Binding dan khusus melalui @propertyWrapper. Mengurangi kode boilerplate dan membuat niat eksplisit melalui anotasi.
  • Generics — fungsi dan tipe type-safe dengan batasan where. Protocol + tipe terkait untuk abstraksi. Pustaka standar Swift sepenuhnya dibangun di atas generics.
  • Pemrograman Berorientasi Protokol — komposisi perilaku melalui extension protokol. Implementasi default memungkinkan penggunaan kembali kode tanpa pewarisan kelas.
  • Enum dengan nilai terkait — model yang kuat untuk status. Setiap kasus menyimpan data unik. Pencocokan pola menjamin semua status ditangani.
  • Extension — menambahkan metode, properti terhitung, dan kesesuaian protokol untuk tipe apa pun, termasuk enum. Kode tetap modular dan bersih tanpa mengubah deklarasi asli.

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.

Diskusikan proyek