body: vad är det, beräknad View-egenskap i SwiftUI

Författare: IT Sectr Publicerad: 2026-06-24 Lästid: 7 min

Egenskapen body — det centrala elementet i View-protokollet i SwiftUI som bestämmer vilket innehåll som visas på skärmen. Enligt Apple Developer Documentation, 2024 är body det enda obligatoriska kravet i View-protokollet och returnerar en typ som följer samma protokoll. SwiftUI anropar body vid varje tillståndsändring för att bygga och jämföra det nya elementträdet.

Huvudpunkter

  • body — beräknad egenskap, obligatorisk för alla typer som implementerar View-protokollet
  • some View — ogenomskinlig returtyp som låter SwiftUI optimera renderingen
  • body anropas vid varje tillståndsändring men ska inte ha bieffekter
  • ViewBuilder omsluter implicit body om den returnerar flera element
  • body anropas inte om identiteten och tillståndet för View inte har ändrats

Vad är body i SwiftUI?

body — är en beräknad egenskap (computed property) som är det enda obligatoriska kravet i View-protokollet. Varje struktur som följer View måste implementera body. Egenskapen returnerar innehållet som SwiftUI visar på skärmen — det kan vara text, bild, knapp, behållare med nästlade element eller någon annan typ som följer View-protokollet.

Signaturen för body är alltid fast: var body: some View { get }. Returtypen är some View (ogenomskinlig typ), inte en konkret typ. Detta innebär att olika View kan returnera olika konkreta typer i body, men Swift-kompilatorn fastställer den konkreta typen för varje implementering i kompileringsfasen.

Enligt WWDC 2022 är body ingångspunkten till den deklarativa beskrivningen av gränssnittet. Till skillnad från UIKit, där du imperativt skapar och konfigurerar UIView, beskriver du i SwiftUI deklarativt vad som ska visas och SwiftUI beräknar själv hur det ska implementeras.

body som ren funktion

Body bör bete sig som en ren funktion — med samma indata (strukturens egenskaper och tillstånd) bör den returnera samma View-träd. Om body är beroende av externt föränderligt tillstånd (globala variabler, UserDefaults utan @AppStorage-omslag) blir beteendet oförutsägbart och SwiftUI kan rita om skärmen felaktigt.

Hur fungerar den beräknade egenskapen body

Beräknad egenskap body lagrar inte värdet — den beräknas varje gång den nås. När SwiftUI bestämmer att tillståndet har ändrats, återskapar det View-strukturen och läser det nya värdet för body för att få det uppdaterade elementträdet för visning.

swift
struct CounterView: View {
    @State private var count = 0

    var body: some View {
        VStack {
            Text("Räknare: \(count)")
                .font(.largeTitle)
            Button("Öka") {
                count += 1
            }
            .padding()
            .background(.blue)
            .foregroundColor(.white)
            .cornerRadius(8)
        }
    }
}

I detta exempel returnerar body en VStack som innehåller Text och en knapp med modifierare. När knappen trycks ökar @State-egenskapen count, SwiftUI återskapar CounterView-strukturen och anropar body igen för att få det uppdaterade trädet med det nya Text-värdet.

Modifierare (.font, .padding, .background, .foregroundColor, .cornerRadius) ändrar inte den ursprungliga View utan omsluter den i ModifiedContent — en ny typ som lägger till modifieringen. Varje modifierare skapar ytterligare en nivå av nästling, vilket är viktigt att beakta för prestanda.

body och den ogenomskinliga typen some View

some View i returtypen för body — är inte bara en konvention, utan ett obligatoriskt krav från kompilatorn. Swift kräver att alla returvägar i body har samma konkreta typ. Utan @ViewBuilder kan du inte returnera Text i en gren och Button i en annan — kompilatorn ger ett fel.

swift
struct ConditionalView: View {
    var isReady: Bool

    @ViewBuilder
    var body: some View {
        if isReady {
            Text("Redo")
                .foregroundColor(.green)
        } else {
            ProgressView()
        }
    }
}

@ViewBuilder på body möjliggör användning av villkorslogik (if/else, switch) utan kompileringsfel. ViewBuilder omsluter automatiskt olika grenar i ConditionalContent — en speciell typ som döljer skillnaderna mellan konkreta typer. Detta är en nyckelfunktion för att bygga dynamiska gränssnitt.

Utan @ViewBuilder försöker kompilatorn härleda en enhetlig typ för alla returvägar. Om typerna är olika — uppstår ett fel. Därför tillämpar SwiftUI implicit @ViewBuilder på body i View-deklarationer, även om annoteringen i användarkod måste placeras explicit för anpassade metoder och egenskaper som returnerar flera View.

Prestanda för some View

Att använda some View istället för en konkret typ minskar inte prestandan — kompilatorn känner i kompileringsfasen till den exakta typen och genererar direkt kod utan dynamisk sändning. AnyView använder däremot typradering (type erasure) med överhead för packning i en existentiell behållare.

Livscykel för body: när och hur anropas den

body anropas av SwiftUI i tre huvudsakliga scenarier: vid första visningen av View, vid ändring av @State/@Binding/@ObservedObject/@StateObject och vid ändring av förälder-View som skickar nya värden via initieraren. SwiftUI kan också anropa body vid ändring av miljövärden (@Environment).

Anropsfrekvensen för body bör inte oroa dig — SwiftUI optimerar omritning genom identitetsmekanismen. Varje View i hierarkin har en unik identifierare. Om identiteten och indata inte har ändrats — anropas body inte, även om förälder-View har ritats om. Detta uppnås genom Equatable-jämförelse och stabilitet hos strukturer.

swift
struct ParentView: View {
    var body: some View {
        ChildView(name: "Alice") // Stabil identitet
    }
}

struct ChildView: View {
    let name: String
    var body: some View {
        Text("Hej, \(name)!")
    }
}

I detta exempel, om ParentView ritas om men skickar samma name-värde — anropas inte ChildView.body. SwiftUI jämför strukturens indata och om de inte har ändrats hoppar det över omritningen av barnkomponenten. Detta är mekanismen för view-differentiering (view differentiation).

När body anropas oväntat

Det finns flera fallgropar som leder till oväntade anrop av body: användning av klasser utan ObservableObject, överföring av slutningar som skapas inuti body (varje skapande av slutning ger en ny identitet) och felaktig användning av EquatableView. Om body anropas för ofta — kontrollera identitetsstabiliteten för alla barnkomponenter.

Bästa praxis för att arbeta med body

Första regeln: body bör vara minimal. Flytta komplex logik till separata beräknade egenskaper eller metoder som returnerar View. Detta förbättrar läsbarheten och låter SwiftUI mer exakt bestämma vilka delar av hierarkin som har ändrats. Dela upp stora body i underkomponenter med tydliga ansvarsgränser.

Andra regeln: använd inte body för att utföra arbete. Datainläsning, nätverksarbete, databasskrivning — allt detta bör ske utanför body, i uppgifter (task), onChange-modifierare eller via ObservableObject. Body är endast avsedd för deklaration av gränssnittet.

Tredje regeln: använd egenskapen EquatableView eller anpassat Equatable-protokoll för View, om standardjämförelse av strukturer inte är tillräcklig. Detta låter dig explicit ange för SwiftUI när en underordnad View kräver omritning och undvika onödiga anrop av body.

Fjärde regeln: om body innehåller komplexa beräkningar (formatering, filtrering, sortering) — använd @State för cachning av resultatet eller flytta beräkningarna till en separat metod som anropas från onChange. Upprepade beräkningar i body vid varje tillståndsuppdatering — en vanlig orsak till animationsfördröjningar.

Femte regeln: för listor (List, ForEach) tillhandahåll stabila identifierare via parametern id. Utan stabil identitet återskapar ForEach alla element vid varje ändring och anropar body för var och en av dem, även om endast ett element har ändrats.

Vanliga frågor

Vad är body i SwiftUI?

body — den beräknade egenskapen för View-protokollet som returnerar innehåll för visning. Det är det enda obligatoriska kravet i protokollet. Returtypen är some View, vilket låter SwiftUI optimera hierarkin i kompileringsfasen.

Kan body anropas flera gånger?

Ja, SwiftUI anropar body vid varje tillståndsändring (@State, @Binding, @ObservedObject) eller ändring av indata. Detta är normalt beteende för ett deklarativt ramverk. SwiftUI optimerar anropsfrekvensen genom identitetsmekanismen och Equatable-jämförelse.

Varför returnerar body some View och inte en konkret typ?

some View — en ogenomskinlig typ som låter dig dölja den konkreta implementeringen. Kompilatorn fastställer typen i kompileringsfasen och säkerställer prestanda för direktanrop. Detta ger flexibilitet: du kan ändra returtypen utan att ändra signaturen.

Kan man returnera nil från body?

Nej, body kan inte vara valfri — returtypen some View tillåter inte nil. Om du behöver dölja ett element villkorligt, använd villkorslogik inuti @ViewBuilder eller returnera EmptyView, som inte upptar plats i hierarkin.

Påverkar antalet modifierare prestandan för body?

Varje modifierare skapar ett nytt lager av ModifiedContent, vilket ökar hierarkins djup. För de flesta skärmar (upp till 50 modifierare) är påverkan omärkbar. Ett alltför stort antal modifierare (hundratals) kan sakta ner diffing. Gruppera relaterade modifierare i anpassade tillägg.

Sammanfattning

  • body — den obligatoriska beräknade egenskapen för View-protokollet som bestämmer skärminnehållet
  • some View — ogenomskinlig returtyp som döljer den konkreta implementeringen från anropande kod
  • @ViewBuilder tillämpas implicit på body för att stödja villkorslogik och flera element
  • body bör inte innehålla bieffekter — det är en ren deklaration av gränssnittet
  • SwiftUI optimerar body-anrop genom identitetsmekanismen och Equatable-jämförelse
  • Dela upp stora body i underkomponenter för bättre prestanda och läsbarhet
  • AnyView ökar överhead — använd @ViewBuilder och Group istället för typradering

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.

Diskutera projektet

Läs också