Suspended — wat is het, bevriezen van app op de achtergrond iOS

Auteur: IT Sectr Gepubliceerd: 2026-03-03 Leestijd: 11 min

Suspended — geschorste toestand van de levenscyclus van een iOS-app, waarin deze in het geheugen is bevroren, maar geen code uitvoert. We laten zien hoe Suspended werkt, welke risico's het bevriezen van een app op de achtergrond met zich meebrengt, hoe iOS het ontladen van Suspended-apps beheert en hoe je state restoration implementeert voor naadloos herstel na terugkeer uit Suspended.

Belangrijkste punten

  • Suspended — app is bevroren in het geheugen, code wordt niet uitgevoerd, UI-stack blijft behouden
  • iOS Suspended — unieke toestand die niet bestaat in Android; proces bestaat, maar is niet actief
  • Ontladen — bij geheugengebrek worden Suspended-apps als eerste verwijderd, gegevens in het geheugen gaan verloren
  • State Restoration — iOS-mechanisme voor het opslaan en herstellen van de UI-stack na ontladen
  • didEnterBackground — laatste methode die gegarandeerd wordt aangeroepen vóór Suspended

Suspended — wat voor toestand is dit

Suspended — de toestand van de levenscyclus van een iOS-app waarin deze zich in het werkgeheugen van het apparaat bevindt, maar geen code uitvoert. Dit is de laatste toestand vóór volledige beëindiging: de app gaat van Background naar Suspended na het voltooien van alle achtergrondtaken of na het verstrijken van de timeout. In Suspended is de app volledig bevroren — alle threads zijn onderbroken, timers werken niet, netwerkactiviteit vindt niet plaats.

Suspended — een unieke eigenschap van iOS die niet voorkomt in de standaard levenscyclus van Android. De reden is een andere architectuur van procesbeheer. iOS bewaart het beeld van de app in het geheugen (analoog aan hibernatie op een desktop) om bij terugkeer van de gebruiker de interface onmiddellijk te herstellen zonder cold start. Android heeft geen Suspended — het proces bestaat ofwel en kan code uitvoeren (Background), ofwel is beëindigd (Not Running), hoewel Android de uitvoering van threads kan onderbreken via LMK.

Voor de gebruiker lijkt Suspended op onmiddellijk herstel: hij schakelt tussen apps via App Switcher en elke app opent op dezelfde plek waar hij hem heeft achtergelaten. Dit wekt de illusie dat alle apps tegelijkertijd werken. In werkelijkheid zijn de meeste bevroren in Suspended. Hot start vanuit Suspended is vele malen sneller dan cold start vanuit Not Running, omdat de code al in het geheugen is geladen.

Hoe het systeem Suspended beheert

iOS volgt de toestand van alle apps en beslist over het ontladen van Suspended-apps op basis van beschikbaar geheugen. Bij geheugentekort begint het systeem Suspended-apps te ontladen, te beginnen met de apps die het langst in deze toestand verkeren. Als er nog steeds onvoldoende geheugen is, verplaatst het systeem apps van Background en Inactive naar Suspended en ontlaadt ze vervolgens. Dit proces is volledig transparant voor de gebruiker — hij ziet alleen het pictogram van de app in App Switcher, die bij klikken een cold start start.

KenmerkSuspended (iOS)Background (iOS)Background (Android)
Code wordt uitgevoerdNeeJa (beperkt)Ja (beperkt)
In geheugenJaJaJa
CPU-verbruik0%LaagLaag
Hot startJa — onmiddellijk herstelJa — via InactiveNee — proces kan zijn gedood
TimeoutNee — kan uren in geheugen blijven~30 seconden (na beginBackgroundTask)Afhankelijk van API-versie
Ontladen door systeemBij geheugengebrekBij kritisch geheugengebrekLMK (Low Memory Killer)
Terugkeer naar werkVanuit App Switcher — onmiddellijkVanuit App Switcher — via InactiveCold start
State RestorationAanbevolenNiet vereistSavedStateHandle

Suspended in iOS: mechanisme van bevriezen

In iOS wordt Suspended automatisch bereikt na voltooiing van alle achtergrondtaken. Het systeem roept applicationDidEnterBackground aan, geeft tijd voor het uitvoeren van beginBackgroundTask (ongeveer 30 seconden), waarna het alle threads geforceerd onderbreekt en de app naar de Suspended-toestand verplaatst. Objecten in het geheugen blijven behouden, maar er wordt geen code uitgevoerd — de app is bevroren in de huidige toestand.

Kritiek belangrijk moment: applicationDidEnterBackground — de laatste methode die gegarandeerd wordt aangeroepen vóór Suspended. Hierna ontvangt de app geen meldingen meer over ontladen uit het geheugen. Als de gebruiker of het systeem een app in Suspended doodt, wordt noch applicationWillTerminate, noch opnieuw applicationDidEnterBackground aangeroepen. Daarom moet alle gegevensopslag plaatsvinden in applicationDidEnterBackground, niet in applicationWillTerminate.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Laatste gegarandeerde aanroep vóór Suspended
    func applicationDidEnterBackground(_ application: UIApplication) {
        // Alles opslaan wat het ontladen uit het geheugen moet overleven
        savePersistentState()
        saveNavigationStack()

        // Extra tijd vragen indien nodig
        let task = application.beginBackgroundTask {
            application.endBackgroundTask(task)
        }
    }

    // Terugkeer uit Suspended — hot start
    func applicationWillEnterForeground(_ application: UIApplication) {
        // App was in Suspended, keren terug naar werk
        print("Terugkeer uit Suspended of Background")
    }

    // Volledig herstel na ontladen uit geheugen
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Als dit een cold start is na ontladen uit Suspended —
        // state restoration herstellen
        return true
    }

    private func savePersistentState() {
        UserDefaults.standard.set(Date(), forKey: "lastActiveDate")
    }

    private func saveNavigationStack() {
        guard let rootVC = window?.rootViewController else { return }
        // Huidige navigatiestack opslaan
        if let navController = rootVC as? UINavigationController {
            let vcClasses = navController.viewControllers.map { type(of: $0) }
            UserDefaults.standard.set(vcClasses.map { NSStringFromClass($0) }, forKey: "navStack")
        }
    }
}

De code toont de kritieke verwerking van Suspended op iOS. applicationDidEnterBackground — de laatste gegarandeerde aanroep. Alle gegevensopslag moet hier plaatsvinden: gebruikersstatus, navigatiestack, concepten, timers. applicationWillEnterForeground wordt aangeroepen bij terugkeer uit Suspended of Background. didFinishLaunchingWithOptions — alleen bij cold start, wanneer de app uit het geheugen is ontladen na Suspended.

Suspended in Android — bestaat er een analoog

In Android bestaat geen directe analoog van iOS Suspended. Android bevriest apps niet in het geheugen met behoud van uitvoeringscontext. In plaats daarvan houdt Android het proces ofwel op de achtergrond (Background), ofwel beëindigt het (Not Running). Echter, op Android 11+ (API 30) is het mechanisme App Freezer verschenen, dat de uitvoering van achtergrondprocessen onderbreekt met het SIGSTOP-signaal. Dit is een functionele analoog van Suspended, maar met belangrijke verschillen.

App Freezer — onderdeel van het Android-geheugenbeheersysteem. Wanneer een app lang op de achtergrond staat en geen actieve meldingen heeft, stuurt het systeem SIGSTOP, waardoor alle threads worden onderbroken. Bij terugkeer van de app naar de voorgrond wordt SIGCONT gestuurd en wordt de uitvoering hervat. Belangrijk verschil met iOS: App Freezer garandeert niet het behoud van de toestand — gegevens in het geheugen kunnen verloren gaan als het proces tijdens het bevriezen wordt gedood.

Op Android wordt het gebruik van SavedStateHandle aanbevolen in ViewModel voor het automatisch opslaan van de toestand bij elke procesbeëindiging. SavedStateHandle slaat gegevens op in Bundle via onSaveInstanceState, die zowel App Freezer als Process Death overleeft. In tegenstelling tot iOS, waar ontladen uit Suspended een uitzonderlijke situatie is, is Process Death op Android normaal gedrag dat altijd verwacht moet worden.

kotlin
// SavedStateHandle — redding van Process Death op Android
class CheckoutViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    // Toestand die het proces overleeft, zelfs na App Freezer
    var currentStep: MutableLiveData<Int> =
        savedStateHandle.getLiveData("checkout_step", 1)

    var cartItems: MutableLiveData<List<CartItem>> =
        savedStateHandle.getLiveData("cart_items", emptyList())

    fun proceedToNextStep() {
        currentStep.value = (currentStep.value ?: 0) + 1
    }

    fun addToCart(item: CartItem) {
        val updatedList = (cartItems.value ?: emptyList()) + item
        cartItems.value = updatedList
        savedStateHandle["cart_items"] = updatedList
    }
}

// Opslaan in onStop voor het geval van App Freezer
class MainActivity : AppCompatActivity() {

    override fun onStop() {
        super.onStop()
        // Gegevens opslaan die het bevriezen moeten overleven
        saveDraftData()
        // Bronnen vrijgeven die niet nodig zijn in bevroren toestand
        releaseHeavyResources()
        // Waarschuwen dat de app wordt bevroren
        // (Loggen voor foutopsporing)
        Log.d("Lifecycle", "Activity gestopt — mogelijke App Freeze")
    }
}

De code toont de aanpak voor het verwerken van de Suspended-analoog op Android. SavedStateHandle in ViewModel slaat automatisch gegevens op en herstelt ze bij Process Death. onStop — de laatste gegarandeerde gebeurtenis vóór mogelijke App Freezer of procesbeëindiging. De status van het bestelformulier, de lijst met producten in de winkelwagen — al deze gegevens overleven het bevriezen dankzij SavedStateHandle. Voor zware bronnen (bitmaps, database-cursors) is onStop de plek om geheugen vrij te geven.

State Restoration: herstel na Suspended

State Restoration — het ingebouwde iOS-mechanisme voor het opslaan en herstellen van de UI-toestand na het ontladen van de app uit het geheugen. Als de app in Suspended was en het systeem heeft deze ontladen, herstelt state restoration bij de volgende cold start de navigatiestack, scrollpositie, formulierstatus en andere UI-elementen. De gebruiker keert terug naar hetzelfde scherm waar hij was gebleven.

State Restoration werkt via de protocollen UIViewControllerRestoration en UIStateRestoring. De ontwikkelaar kent restorationIdentifier toe aan elke ViewController en View die hij wil herstellen. Bij het gaan naar Background codeert iOS de toestand van deze objecten. Na terugkeer uit ontladen maakt iOS nieuwe objecten aan en decodeert de opgeslagen toestand. Zonder state restoration ziet de gebruiker een leeg scherm na cold start in plaats van de plek waar hij was gebleven.

swift
import UIKit

class DetailViewController: UIViewController {

    var itemID: String = ""
    var scrollPosition: CGPoint = .zero

    override func viewDidLoad() {
        super.viewDidLoad()
        restorationIdentifier = "DetailViewController"
        restorationClass = type(of: self)
    }

    override func encodeRestorableState(with coder: NSCoder) {
        super.encodeRestorableState(with: coder)
        coder.encode(itemID, forKey: "itemID")
        coder.encode(scrollPosition, forKey: "scrollPosition")
    }

    override func decodeRestorableState(with coder: NSCoder) {
        super.decodeRestorableState(with: coder)
        if let savedID = coder.decodeObject(forKey: "itemID") as? String {
            itemID = savedID
            loadItem()
        }
        if let savedPosition = coder.decodeCGPoint(forKey: "scrollPosition") {
            scrollPosition = savedPosition
            // Positie herstellen na het laden van gegevens
        }
    }
}

// AppDelegate — activering van State Restoration
func application(
    _ application: UIApplication,
    shouldSaveSecureApplicationState coder: NSCoder
) -> Bool {
    return true
}

func application(
    _ application: UIApplication,
    shouldRestoreSecureApplicationState coder: NSCoder
) -> Bool {
    return true
}

De code toont de implementatie van State Restoration op iOS. restorationIdentifier en restorationClass zijn noodzakelijk voor elke te herstellen ViewController. encodeRestorableState/decodeRestorableState slaan gegevens op en laden ze via NSCoder. In AppDelegate schakelen shouldSaveSecureApplicationState en shouldRestoreSecureApplicationState gecodeerde opslag van de toestand in. Vanaf iOS 12+ wordt het gebruik van secure encoding (NSSecureCoding) aanbevolen voor gegevensbescherming.

Beste praktijken voor werken met Suspended

Eerste regel — ga er nooit van uit dat de app terugkeert uit Suspended. Het systeem kan de app op elk moment ontladen. Alle kritiek belangrijke gegevens moeten vóór de overgang naar Suspended worden opgeslagen in permanente opslag — dat wil zeggen in applicationDidEnterBackground of onStop. UserDefaults, Core Data, File Manager — geschikte opslagplaatsen. Geheugen (variabelen, eigenschappen) — een onbetrouwbare opslag voor gegevens die Suspended moeten overleven.

Tweede regel — geef bronnen vrij vóór Suspended. Sluit bestandsdescriptoren, geef GPU-geheugen vrij (Metal, Core Graphics), sluit netwerkverbindingen. Hoewel de app geen CPU verbruikt in Suspended, worden bezette bronnen geblokkeerd voor andere apps. Op iOS in Suspended mogen geen open sockets worden gehouden — bij terugkeer uit Suspended kunnen ze niet werken, wat fouten veroorzaakt.

Derde regel — plaats geen tijdsafhankelijke logica in afwachting van terugkeer uit Suspended. Timers, callbacks en netwerkactiviteit stoppen in Suspended. Als de app enkele uren in Suspended is geweest, kan de timer bij terugkeer onjuist werken. Controleer de actualiteit van gegevens bij terugkeer — mogelijk is de cache verouderd en is het autorisatietoken verlopen.

Vierde regel — gebruik State Restoration voor alle schermen, vooral voor invoerformulieren, scrollbare lijsten en detailschermen. Zonder state restoration ziet de gebruiker na terugkeer uit ontladen Suspended het beginscherm van de app in plaats van de plek waar hij was gebleven. Dit verslechtert de gebruikerservaring en dwingt de gebruiker handelingen te herhalen.

swift
import UIKit

// Controle: is de app uit het geheugen ontladen?
func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    // Controleren of er opgeslagen toestand is
    if UserDefaults.standard.object(forKey: "navStack") != nil {
        // App is ontladen uit Suspended
        // Toestand moet worden hersteld
        restoreNavigationStack()
    } else {
        // Schone cold start vanuit Not Running
        showOnboardingIfNeeded()
    }
    return true
}

private func restoreNavigationStack() {
    guard let savedStack = UserDefaults.standard.array(forKey: "navStack") as? [String],
          let navController = window?.rootViewController as? UINavigationController
    else { return }

    for vcClassName in savedStack {
        if let vcClass = NSClassFromString(vcClassName) as? UIViewController.Type {
            let vc = vcClass.init()
            navController.pushViewController(vc, animated: false)
        }
    }
}

De code toont de praktijk om te bepalen of de app uit Suspended is ontladen. Controle van UserDefaults op de aanwezigheid van een opgeslagen navigatiestack maakt het mogelijk om cold start na ontladen te onderscheiden van schone cold start. In het eerste geval wordt de navigatiestack hersteld, in het tweede wordt onboarding of het hoofdscherm getoond. Deze benadering vult de ingebouwde State Restoration aan voor gevallen waarin NSCoder niet voldoende is.

Veelgestelde vragen

Hoe lang kan een app in Suspended blijven?

Onbeperkt — van enkele seconden tot enkele dagen. iOS heeft geen timeout voor Suspended. De app blijft in het geheugen totdat het systeem besluit deze te ontladen vanwege gebrek aan bronnen. In de praktijk blijven apps 15 minuten tot enkele uren in Suspended, afhankelijk van de hoeveelheid RAM van het apparaat en het aantal actieve apps.

Wordt applicationWillTerminate aangeroepen bij ontladen uit Suspended?

Nee. applicationWillTerminate wordt niet aangeroepen bij het ontladen van de app uit Suspended. Het systeem maakt eenvoudigweg het geheugen vrij zonder de app te waarschuwen. Dit is nog een reden waarom alle gegevensopslag in applicationDidEnterBackground moet plaatsvinden. applicationWillTerminate wordt alleen aangeroepen wanneer de gebruiker de app handmatig beëindigt door te vegen in App Switcher.

Heeft Android een analoog van Suspended?

Er is geen directe analoog. Op Android 11+ is App Freezer verschenen, dat achtergrondprocessen onderbreekt via SIGSTOP — dit is functioneel vergelijkbaar met Suspended. Android-apps moeten echter worden ontworpen met het oog op Process Death op elk moment. Gebruik SavedStateHandle in ViewModel en onSaveInstanceState voor het opslaan van de toestand die zowel App Freezer als Process Death overleeft.

Hoe controleer ik of de app in Suspended is geweest?

In iOS is er geen directe API om dit te controleren. Indirecte methode: controleer UserDefaults op de aanwezigheid van opgeslagen toestand in didFinishLaunchingWithOptions. Als de toestand bestaat — is de app uit Suspended ontladen en start hij koud. Als er geen toestand is — schone cold start. In SwiftUI kun je een flag opslaan in scenePhase.background en deze controleren bij de volgende start.

Wat is snapshot in de context van Suspended?

Bij de overgang naar Suspended maakt iOS een snapshot — een schermafbeelding van de huidige UI van de app. Deze afbeelding wordt getoond in App Switcher en bij terugkeer naar de app (als een ). Als de app vertrouwelijke gegevens bevat, kan de snapshot deze onthullen. Gebruik voor bescherming UIApplication.shouldSnapshotSecureApp (iOS 16+) of pas een blur-overlay toe in applicationDidEnterBackground.

Samenvatting

  • Suspended — app is bevroren in iOS-geheugen, code wordt niet uitgevoerd, maar UI-stack blijft behouden voor onmiddellijk herstel
  • Uniciteit van iOS — Suspended bestaat niet in Android; Android gebruikt App Freezer (SIGSTOP) als gedeeltelijke analoog
  • Ontladen — systeem ontlaadt Suspended-apps als eerste bij geheugengebrek zonder melding
  • Opslaan — applicationDidEnterBackground — laatste gegarandeerde methode, alle gegevens moeten hier worden opgeslagen
  • State Restoration — NSCoder-mechanisme voor automatisch UI-herstel na ontladen uit Suspended
  • Android-alternatief — SavedStateHandle + onSaveInstanceState voor het overleven van Process Death
  • Snapshot — iOS maakt een screenshot bij Suspended; vertrouwelijke gegevens moeten worden verborgen via blur-overlay of secure snapshot

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.

Bespreek het project

Lees ook