Class — är en referenstyp (reference type) i språket Swift, vars instanser skickas via referens, inte kopieras vid tilldelning. Till skillnad från strukturer stöder klasser arv, deinitialisering och automatisk referensräkning ARC för minneshantering. Enligt Swift Programming Language Guide, 2026 är class nödvändigt för att arbeta med Apples UI-ramverk (UIKit, AppKit) och implementera mönster som kräver gemensam objektidentitet. Valet mellan class och struct är ett av de viktigaste arkitekturbesluten i Swift.
Huvudpunkter
Class (klass) — är en sammansatt referenstyp i Swift som grupperar egenskaper och metoder i en enda enhet med stöd för arv och dynamisk sändning. Till skillnad från struct skapas instansen av klassen på heapen och variabeln lagrar en referens till denna instans, inte själva datan.
När du tilldelar en klassvariabel till en annan variabel refererar båda till samma objekt i minnet. Ändringar via en referens är synliga via den andra — detta är den grundläggande egenskapen för reference types, som används i mönster för delegering, observation och delat tillstånd.
Enligt Apple Swift Documentation är klasser det enda sättet att arbeta med UIKit och AppKit, där alla UI-komponenter ärver från UIView och UIViewController. Dessutom är klasser nödvändiga för att implementera mönster som kräver objektidentitet (två referenser till ett objekt) och kontrollerad livslängd.
Reference type-semantik — den viktigaste egenskapen hos klasser. Vid tilldelning av en klass till en ny variabel kopierar Swift referensen, inte datan. Alla variabler som refererar till samma instans ser dess aktuella tillstånd och kan ändra det. Detta beteende skiljer sig fundamentalt från value types, där varje variabel får en oberoende kopia.
// Exempel på reference type-semantik
class User {
var name: String
init(name: String) { self.name = name }
}
let user1 = User(name: "Alice")
let user2 = user1 // user2 — samma referens
user2.name = "Bob"
print(user1.name) // "Bob" — ändrad via user2!
// Identitetskontroll med === operatorn
print(user1 === user2) // true — samma objekt
Operatorerna === (identitet) och !== kontrollerar om två variabler refererar till samma instans av klassen. Detta är skillnaden från == (likhet), som jämför värden på egenskaper. För struct är operatorn === inte tillgänglig — value types har ingen identitet.
Arv — mekanismen genom vilken en klass kan ärva egenskaper och metoder från föräldraklassen. I Swift kan en klass endast ärva från en förälder (single inheritance), men kan implementera flera protokoll. Nyckelordet override tillåter åsidosättande av en ärvd metod eller egenskap.
Varje klass som inte ärver från en annan klass blir automatiskt en basklass (inte att förväxla med NSObject). Underklassen anger föräldern med kolon efter namnet. Om underklassen åsidosätter förälderns metod måste den anropa super.metod() för att bevara förälderns beteende — detta är ett krav från kompilatorn.
Nyckelordet final före class förbjuder arv. Kompilatorn kan optimera anrop av metoder i final-klasser genom static dispatch, vilket ökar prestandan. Använd final för klasser som inte är avsedda att utökas — det dokumenterar din avsikt och snabbar upp koden.
// Exempel på klassarv i Swift
class Vehicle {
var speed: Double = 0
func description() -> String {
"Speed: \(speed) km/h"
}
}
// Car ärver från Vehicle
class Car: Vehicle {
var brand: String = "Unknown"
override func description() -> String {
"\(brand) - \(speed) km/h"
}
}
// Final class — förhindrar arv
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"
Arv av klasser är en kraftfull men ansvarsfull mekanism. Djup hierarki (5+ nivåer) försvårar underhåll och testning. För återanvändning av funktionalitet utan arv, använd protokoll med extension och protokollorienterad programmering — ett tillvägagångssätt som Apple främjar som alternativ till djupa klasshierarkier.
Swift använder ARC (Automatic Reference Counting) för minneshantering av klasser. Varje instans av en klass har en räknare för starka referenser. När en ny stark referens skapas ökar räknaren; vid förstörelse minskar den. När räknaren når noll frigörs minnet.
Deinit — metod som anropas automatiskt innan instansen av klassen frigörs. I den frigörs resurser: filer stängs, avprenumeration från notifikationer görs, timers stoppas. Deinit finns endast i klasser — strukturer och uppräkningar har det inte.
För att förhindra cykler av starka referenser (retain cycles) tillhandahåller Swift weak och unowned referenser. Weak — en valfri referens som automatiskt blir nil när objektet frigörs. Unowned — icke-valfri, men refererar till ett objekt som garanterat lever längre än det aktuella sammanhanget. En typisk retain cycle uppstår i en parent-child-relation: child håller en stark referens till parent.
// Exempel på ARC och svag referens
class Parent {
var name: String
var child: Child?
init(name: String) { self.name = name }
deinit { print("\(name) avallokerad") }
}
class Child {
var name: String
weak var parent: Parent? // weak förhindrar retain cycle
init(name: String) { self.name = name }
deinit { print("\(name) avallokerad") }
}
var parent: Parent? = Parent(name: "Anna")
parent?.child = Child(name: "Mia")
parent?.child?.parent = parent
parent = nil // Båda objekten avallokerade!
// Utan weak skulle det skapa en retain cycle
Använd alltid weak för referenser från barnobjektet till föräldern och för capture-listor i closures. Använd unowned endast när du är säker på att objektet överlever det aktuella sammanhanget — felaktig användning av unowned kan leda till krasch vid åtkomst av frigjort minne.
Valet mellan class och struct är ett arkitekturbeslut som påverkar prestanda, trådsäkerhet och API-design. Låt oss titta på tabellen över viktiga skillnader som hjälper dig att fatta rätt beslut i varje konkret fall.
| Egenskap | class | struct |
|---|---|---|
| Typ | Reference type (referens) | Value type (kopia) |
| Minne | Heap + ARC | Stack / inline |
| Arv | Stöder (en förälder) | Stöder inte |
| Deinit | Ja | Nej |
| Identitet (===) | Stöder | Stöder inte |
| Mutating | Krävs inte (alltid mutating) | Endast med mutating |
| Memberwise init | Genereras inte | Genereras automatiskt |
| Trådsäkerhet | Inte garanterad (delat tillstånd) | Garanterad (kopiering) |
Använd klasser när du behöver gemensam identitet (flera delar av koden arbetar med ett objekt), arv eller interaktion med Objective-C runtime. För allt annat är strukturer att föredra — de är snabbare, säkrare i flertrådad kod och kräver ingen minneshantering.
Trots Apples rekommendation att använda struct som standard är klasser nödvändiga i flera specifika scenarier. Låt oss undersöka varje med praktiska exempel.
Alla UI-komponenter i iOS och macOS är klasser som ärver från UIView (iOS) eller NSView (macOS). Du kan inte ersätta UIViewController med en struktur — den kräver arv och deinit för att frigöra resurser. När du arbetar med UIKit, använd klasser för kontroller, vyer och deras delegater.
Singleton-mönstret (en instans av en klass för hela applikationen) kräver referenssemantik. Hanterare: NetworkManager, SettingsManager, AnalyticsService — implementeras vanligtvis som klasser med en shared static-egenskap. Strukturer är inte lämpliga eftersom varje kopia skulle vara en oberoende instans.
När ett objekt ska vara den enda källan till sanning (single source of truth) och skickas mellan moduler via referens — använd class. Detta gäller tillståndshantering där en ändring av objektet på ett ställe måste vara synlig i alla beroende komponenter. För ObservableObject i SwiftUI är klasser obligatoriska.
// ObservableObject — class krävs för SwiftUI
import SwiftUI
class AppViewModel: ObservableObject {
@Published var isLoggedIn: Bool = false
@Published var username: String = ""
func login(user: String) {
isLoggedIn = true
username = user
}
}
// Användning i SwiftUI View
struct ContentView: View {
@StateObject var viewModel = AppViewModel()
var body: some View {
Text(viewModel.isLoggedIn ? "Välkommen" : "Logga in")
}
}
Regel: om ett objekt ska ha identitet (två referenser -> ett objekt), vara en unik instans eller arbeta med UIKit/Objective-C — välj class. Om objektet bara lagrar data — välj struct.
Vanliga frågor
Class — är en referenstyp (reference type) i Swift som stöder arv, deinitialisering och ARC för minneshantering. Instanser av klasser lagras på heapen och variabler innehåller en referens till objektet, inte en kopia av det.
Class — reference type (skickas via referens), stöder arv och deinit. Struct — value type (kopieras), stöder inte arv, men implementerar protokoll och får memberwise init automatiskt. Swift rekommenderar struct som standardtyp.
ARC (Automatic Reference Counting) — minneshanteringsmekanism för Swift-klasser. Varje instans har en räknare för starka referenser. När räknaren når noll frigörs minnet. Weak och unowned referenser förhindrar retain cycles mellan objekt.
Deinit — klassens metod som anropas automatiskt innan dess minne frigörs. Används för att stänga filer, avsluta prenumerationer på notifikationer och andra avslutande operationer. Deinit finns endast i klasser — strukturer har det inte.
Använd class för UIKit/AppKit UI-komponenter, singleton, ObservableObject i SwiftUI, objekt med gemensam identitet (delegate, observer) och vid arbete med Objective-C runtime. För datamodeller, DTO:er och konfigurationer är struct att föredra.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också