Class — is een referentietype (reference type) in de taal Swift, waarvan instanties worden doorgegeven via referentie, niet gekopieerd bij toewijzing. In tegenstelling tot structuren ondersteunen klassen overerving, deïnitialisatie en automatische referentietelling ARC voor geheugenbeheer. Volgens de Swift Programming Language Guide, 2026 is class noodzakelijk voor het werken met Apple UI-frameworks (UIKit, AppKit) en het implementeren van patronen die een gedeelde objectidentiteit vereisen. De keuze tussen class en struct is een van de belangrijkste architectonische beslissingen in Swift.
Belangrijkste punten
Class (klasse) — is een samengesteld referentietype in Swift dat eigenschappen en methoden groepeert in één entiteit met ondersteuning voor overerving en dynamische dispatch. In tegenstelling tot struct wordt een klasse-instantie aangemaakt in de heap en slaat de variabele een referentie naar deze instantie op, niet de gegevens zelf.
Wanneer u een klassevariabele aan een andere variabele toewijst, verwijzen beide naar hetzelfde object in het geheugen. Wijzigingen via de ene referentie zijn zichtbaar via de andere — dit is de fundamentele eigenschap van reference types, gebruikt in patronen voor delegatie, observatie en gedeelde toestand.
Volgens Apple Swift Documentation zijn klassen de enige manier om met UIKit en AppKit te werken, waar alle UI-componenten overerven van UIView en UIViewController. Bovendien zijn klassen noodzakelijk voor het implementeren van patronen die objectidentiteit vereisen (twee referenties naar één object) en gecontroleerde levensduur.
Reference type semantiek — de belangrijkste eigenschap van klassen. Bij het toewijzen van een klasse aan een nieuwe variabele kopieert Swift de referentie, niet de gegevens. Alle variabelen die naar dezelfde instantie verwijzen, zien de huidige toestand en kunnen deze wijzigen. Dit gedrag verschilt fundamenteel van value types, waarbij elke variabele een onafhankelijke kopie krijgt.
// Voorbeeld van reference type semantiek
class User {
var name: String
init(name: String) { self.name = name }
}
let user1 = User(name: "Alice")
let user2 = user1 // user2 — zelfde referentie
user2.name = "Bob"
print(user1.name) // "Bob" — gewijzigd via user2!
// Identiteitscontrole met === operator
print(user1 === user2) // true — zelfde object
De operatoren === (identiteit) en !== controleren of twee variabelen naar dezelfde klasse-instantie verwijzen. Dit is het verschil met == (gelijkheid), dat de waarden van eigenschappen vergelijkt. Voor struct is de operator === niet beschikbaar — value types hebben geen identiteit.
Overerving — het mechanisme waarbij een klasse eigenschappen en methoden van de ouderklasse kan overnemen. In Swift kan een klasse slechts van één ouder overerven (single inheritance), maar kan meerdere protocollen implementeren. Het sleutelwoord override maakt het mogelijk om een overgeërfde methode of eigenschap te overschrijven.
Elke klasse die niet van een andere klasse overerft, wordt automatisch een basisklasse (niet te verwarren met NSObject). De subklasse geeft de ouder aan met een dubbele punt na de naam. Als de subklasse de methode van de ouder overschrijft, moet deze super.methode() aanroepen om het gedrag van de ouder te behouden — dit is een vereiste van de compiler.
Het sleutelwoord final voor class verbiedt overerving. De compiler kan aanroepen van methoden van final-klassen optimaliseren via static dispatch, wat de prestaties verhoogt. Gebruik final voor klassen die niet bedoeld zijn om uit te breiden — dit documenteert uw intentie en versnelt de code.
// Voorbeeld van klasseovererving in Swift
class Vehicle {
var speed: Double = 0
func description() -> String {
"Speed: \(speed) km/h"
}
}
// Car erft van Vehicle
class Car: Vehicle {
var brand: String = "Unknown"
override func description() -> String {
"\(brand) - \(speed) km/h"
}
}
// Final class — voorkomt overerving
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"
Overerving van klassen is een krachtig maar verantwoordelijk mechanisme. Een diepe hiërarchie (5+ niveaus) maakt onderhoud en testen moeilijk. Voor herbruikbaarheid van functionaliteit zonder overerving gebruikt u protocollen met extension en protocol-georiënteerd programmeren — een benadering die Apple promoot als alternatief voor diepe klassehiërarchieën.
Swift gebruikt ARC (Automatic Reference Counting) voor het beheer van klassegeheugen. Elke klasse-instantie heeft een teller voor sterke referenties. Bij het maken van een nieuwe sterke referentie stijgt de teller; bij vernietiging daalt deze. Wanneer de teller nul bereikt, wordt het geheugen vrijgemaakt.
Deinit — methode die automatisch wordt aangeroepen voor het vrijmaken van de klasse-instantie. Hierin worden bronnen vrijgemaakt: bestanden worden gesloten, meldingen worden opgezegd, timers worden gestopt. Deinit bestaat alleen bij klassen — structuren en opsommingen hebben het niet.
Om cycli van sterke referenties (retain cycles) te voorkomen, biedt Swift weak en unowned referenties. Weak — een optionele referentie die automatisch nil wordt bij het vrijmaken van het object. Unowned — niet-optioneel, maar verwijst naar een object dat gegarandeerd langer leeft dan de huidige context. Een typische retain cycle ontstaat in een parent-child relatie: child houdt een sterke referentie naar parent vast.
// Voorbeeld van ARC en weak referentie
class Parent {
var name: String
var child: Child?
init(name: String) { self.name = name }
deinit { print("\(name) gedealloceerd") }
}
class Child {
var name: String
weak var parent: Parent? // weak voorkomt retain cycle
init(name: String) { self.name = name }
deinit { print("\(name) gedealloceerd") }
}
var parent: Parent? = Parent(name: "Anna")
parent?.child = Child(name: "Mia")
parent?.child?.parent = parent
parent = nil // Beide objecten gedealloceerd!
// Zonder weak zou het een retain cycle creëren
Gebruik altijd weak voor referenties van het kindobject naar de ouder en voor capture-lijsten in closures. Gebruik unowned alleen wanneer u zeker weet dat het object de huidige context overleeft — onjuist gebruik van unowned kan leiden tot een crash bij toegang tot vrijgemaakt geheugen.
De keuze tussen class en struct is een architectonische beslissing die invloed heeft op prestaties, threadveiligheid en API-ontwerp. Laten we de tabel met belangrijkste verschillen bekijken die helpt bij het nemen van de juiste beslissing in elk concreet geval.
| Kenmerk | class | struct |
|---|---|---|
| Type | Reference type (referentie) | Value type (kopie) |
| Geheugen | Heap + ARC | Stack / inline |
| Overerving | Ondersteunt (één ouder) | Ondersteunt niet |
| Deinit | Ja | Nee |
| Identiteit (===) | Ondersteunt | Ondersteunt niet |
| Mutating | Niet vereist (altijd mutating) | Alleen met mutating |
| Memberwise init | Wordt niet gegenereerd | Wordt automatisch gegenereerd |
| Threadveiligheid | Niet gegarandeerd (gedeelde toestand) | Gegarandeerd (kopiëren) |
Gebruik klassen wanneer u gedeelde identiteit nodig heeft (meerdere delen van de code werken met één object), overerving of interactie met Objective-C runtime. Al het andere heeft de voorkeur voor structuren — ze zijn sneller, veiliger in multi-thread code en vereisen geen geheugenbeheer.
Ondanks de aanbeveling van Apple om standaard struct te gebruiken, zijn klassen noodzakelijk in een aantal specifieke scenario's. Laten we elk scenario met praktische voorbeelden bekijken.
Alle UI-componenten in iOS en macOS zijn klassen die overerven van UIView (iOS) of NSView (macOS). U kunt UIViewController niet vervangen door een struct — het vereist overerving en deinit voor het vrijmaken van bronnen. Bij het werken met UIKit gebruikt u klassen voor controllers, views en hun delegates.
Het Singleton patroon (één instantie van een klasse voor de hele applicatie) vereist referentiesemantiek. Managers: NetworkManager, SettingsManager, AnalyticsService — worden meestal geïmplementeerd als klassen met een shared static property. Structuren zijn niet geschikt omdat elke kopie een onafhankelijke instantie zou zijn.
Wanneer een object de enige bron van waarheid (single source of truth) moet zijn en tussen modules via referentie wordt doorgegeven — gebruik dan class. Dit betreft toestandsbeheer waarbij een wijziging van het object op één plek zichtbaar moet zijn in alle afhankelijke componenten. Voor ObservableObject in SwiftUI zijn klassen verplicht.
// ObservableObject — class vereist voor SwiftUI
import SwiftUI
class AppViewModel: ObservableObject {
@Published var isLoggedIn: Bool = false
@Published var username: String = ""
func login(user: String) {
isLoggedIn = true
username = user
}
}
// Gebruik in SwiftUI View
struct ContentView: View {
@StateObject var viewModel = AppViewModel()
var body: some View {
Text(viewModel.isLoggedIn ? "Welkom" : "Inloggen")
}
}
Regel: als een object identiteit moet hebben (twee referenties -> één object), een unieke instantie moet zijn of met UIKit/Objective-C moet werken — kies class. Als het object alleen gegevens opslaat — kies struct.
Veelgestelde vragen
Class — is een referentietype (reference type) in Swift dat overerving, deïnitialisatie en ARC voor geheugenbeheer ondersteunt. Instanties van klassen worden opgeslagen in de heap en variabelen bevatten een referentie naar het object, niet de kopie ervan.
Class — reference type (doorgegeven via referentie), ondersteunt overerving en deinit. Struct — value type (wordt gekopieerd), ondersteunt geen overerving, maar implementeert protocollen en krijgt automatisch een memberwise init. Swift beveelt struct aan als standaardtype.
ARC (Automatic Reference Counting) — geheugenbeheermechanisme voor Swift-klassen. Elke instantie heeft een teller voor sterke referenties. Wanneer de teller nul bereikt, wordt het geheugen vrijgemaakt. Weak en unowned referenties voorkomen retain cycles tussen objecten.
Deinit — methode van de klasse die automatisch wordt aangeroepen voordat het geheugen wordt vrijgemaakt. Wordt gebruikt voor het sluiten van bestanden, opzeggen van meldingen en andere afsluitende operaties. Deinit bestaat alleen bij klassen — structuren hebben het niet.
Gebruik class voor UIKit/AppKit UI-componenten, singleton, ObservableObject in SwiftUI, objecten met gedeelde identiteit (delegate, observer) en bij het werken met Objective-C runtime. Voor gegevensmodellen, DTO's en configuraties heeft struct de voorkeur.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook