Suspended — nədir, iOS-da tətbiqin fon dondurulması

Müəllif: IT Sectr Dərc olunub: 2026-03-03 Oxuma vaxtı: 11 dəq

Suspended — iOS tətbiqinin həyat dövrünün dayandırılmış vəziyyəti, burada tətbiq yaddaşda dondurulub, lakin kod icra etmir. Suspended-in necə işlədiyini, tətbiqin fon dondurulmasının hansı riskləri daşıdığını, iOS-un Suspended tətbiqlərin boşaldılmasını necə idarə etdiyini və Suspended-dən qayıtdıqdan sonra problemsiz bərpa üçün state restoration-un necə həyata keçiriləcəyini göstəririk.

Əsas məqamlar

  • Suspended — tətbiq yaddaşda dondurulub, kod icra olunmur, UI-stack qorunur
  • iOS Suspended — Android-də olmayan unikal vəziyyət; proses mövcuddur, lakin aktiv deyil
  • Boşaltma — yaddaş çatışmazlığında Suspended tətbiqlər ilk növbədə silinir, yaddaşdakı məlumatlar itir
  • State Restoration — boşaltmadan sonra UI-stack-in saxlanması və bərpası üçün iOS mexanizmi
  • didEnterBackground — Suspended-dən əvvəl zəmanətli çağırılan son metod

Suspended — bu nə vəziyyətdir

Suspended — iOS tətbiqinin həyat dövrünün elə bir vəziyyətidir ki, tətbiq cihazın operativ yaddaşında yerləşir, lakin heç bir kod icra etmir. Bu tam başa çatmadan əvvəlki son vəziyyətdir: tətbiq bütün fon tapşırıqlarını tamamladıqdan sonra və ya vaxt aşımı bitdikdə Background-dan Suspended-ə keçir. Suspended-də tətbiq tamamilə dondurulub — bütün axınlar dayandırılıb, taymerlər işləmir, şəbəkə aktivliyi yoxdur.

Suspended — Android-in standart həyat dövründə olmayan unikal iOS xüsusiyyətidir. Səbəb proses idarəetməsinin fərqli arxitekturasıdır. iOS tətbiqin şəklini yaddaşda saxlayır (desktopdakı hibridasiyaya bənzər), istifadəçi qayıtdıqda soyuq start olmadan interfeysi dərhal bərpa etmək üçün. Android-də Suspended yoxdur — proses ya mövcuddur və kod icra edə bilər (Background), ya da başa çatıb (Not Running), baxmayaraq ki, Android LMK vasitəsilə axınların icrasını dayandıra bilər.

İstifadəçi üçün Suspended ani bərpa kimi görünür: o, App Switcher vasitəsilə tətbiqlər arasında keçid edir və hər tətbiq onu tərk etdiyi yerdən açılır. Bu, bütün tətbiqlərin eyni anda işlədiyi illüziyasını yaradır. Əslində onların çoxu Suspended-də dondurulub. Suspended-dən isti start Not Running-dən soyuq startdan qat-qat sürətlidir, çünki kod artıq yaddaşa yüklənib.

Sistem Suspended-i necə idarə edir

iOS bütün tətbiqlərin vəziyyətini izləyir və mövcud yaddaş əsasında Suspended tətbiqlərin boşaldılması haqqında qərar qəbul edir. Yaddaş çatışmadıqda sistem Suspended tətbiqləri boşaltmağa başlayır, ən uzun müddət bu vəziyyətdə qalanlardan başlayaraq. Əgər yaddaş hələ də çatmırsa, sistem Background və Inactive-dən tətbiqləri Suspended-ə keçirir və sonra boşaldır. Bu proses istifadəçi üçün tamamilə şəffafdır — o, sadəcə App Switcher-də tətbiqin işarəsini görür, kliklədikdə isə soyuq start işə düşür.

XüsusiyyətSuspended (iOS)Background (iOS)Background (Android)
Kod icra olunurXeyrBəli (məhdud)Bəli (məhdud)
YaddaşdaBəliBəliBəli
CPU istehlakı0%AşağıAşağı
İsti startBəli — ani bərpaBəli — Inactive vasitəsiləXeyr — proses öldürülə bilər
Vaxt aşımıXeyr — saatlarla yaddaşda qala bilər~30 saniyə (beginBackgroundTask-dən sonra)API versiyasından asılıdır
Sistem tərəfindən boşaltmaYaddaş çatışmazlığındaKritik yaddaş çatışmazlığındaLMK (Low Memory Killer)
İşə qayıtmaApp Switcher-dən — dərhalApp Switcher-dən — Inactive vasitəsiləSoyuq start
State RestorationArzuolunanTələb olunmurSavedStateHandle

iOS-da Suspended: dondurma mexanizmi

iOS-da Suspended bütün fon tapşırıqları tamamlandıqdan sonra avtomatik əldə edilir. Sistem applicationDidEnterBackground-ı çağırır, beginBackgroundTask-ın icrası üçün vaxt verir (təxminən 30 saniyə), bundan sonra bütün axınları məcburi dayandırır və tətbiqi Suspended vəziyyətinə keçirir. Yaddaşdakı obyektlər qorunur, lakin heç bir kod icra olunmur — tətbiq cari vəziyyətdə dondurulur.

Kritik vacib məqam: applicationDidEnterBackground — Suspended-dən əvvəl zəmanətli çağırılan son metoddur. Bundan sonra tətbiq yaddaşdan boşaldılması haqqında heç bir bildiriş almır. Əgər istifadəçi və ya sistem Suspended vəziyyətində olan tətbiqi öldürürsə, nə applicationWillTerminate, nə də təkrar applicationDidEnterBackground çağırılır. Buna görə bütün məlumatların saxlanması applicationDidEnterBackground-da, applicationWillTerminate-də deyil, baş verməlidir.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Suspended-dən əvvəl son zəmanətli çağırış
    func applicationDidEnterBackground(_ application: UIApplication) {
        // Yaddaşdan boşaldılmanı yaşamalı olan hər şeyi saxlayırıq
        savePersistentState()
        saveNavigationStack()

        // Lazım olduqda əlavə vaxt tələb edirik
        let task = application.beginBackgroundTask {
            application.endBackgroundTask(task)
        }
    }

    // Suspended-dən qayıtma — isti start
    func applicationWillEnterForeground(_ application: UIApplication) {
        // Tətbiq Suspended-də idi, işə qayıdırıq
        print("Suspended və ya Background-dan qayıtma")
    }

    // Yaddaşdan boşaltmadan sonra tam bərpa
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Əgər bu Suspended-dən boşaltmadan sonra soyuq startdırsa —
        // state restoration-u bərpa edirik
        return true
    }

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

    private func saveNavigationStack() {
        guard let rootVC = window?.rootViewController else { return }
        // Cari naviqasiya stack-ini saxlayırıq
        if let navController = rootVC as? UINavigationController {
            let vcClasses = navController.viewControllers.map { type(of: $0) }
            UserDefaults.standard.set(vcClasses.map { NSStringFromClass($0) }, forKey: "navStack")
        }
    }
}

Kod iOS-da Suspended-in kritik vacib işlənməsini göstərir. applicationDidEnterBackground — son zəmanətli çağırış. Bütün məlumatların saxlanması burada baş verməlidir: istifadəçi vəziyyəti, naviqasiya stack-i, qaralamalar, taymerlər. applicationWillEnterForeground Suspended və ya Background-dan qayıtdıqda çağırılır. didFinishLaunchingWithOptions — yalnız soyuq startda, tətbiq Suspended-dən sonra yaddaşdan boşaldıldıqda.

Android-də Suspended — analoqu varmı

Android-də birbaşa analoqu yoxdur iOS Suspended. Android tətbiqləri icra kontekstini qoruyaraq yaddaşda dondurmur. Bunun əvəzinə Android ya prosesi fonda saxlayır (Background), ya da onu başa çatdırır (Not Running). Lakin Android 11+-də (API 30) App Freezer mexanizmi meydana çıxdı, o SIGSTOP siqnalı ilə fon proseslərinin icrasını dayandırır. Bu, Suspended-in funksional analoqudur, lakin əhəmiyyətli fərqlərlə.

App Freezer — Android yaddaş idarəetmə sisteminin bir hissəsidir. Tətbiq uzun müddət fonda qaldıqda və aktiv bildirişləri olmadıqda, sistem ona SIGSTOP göndərir, bütün axınları dayandırır. Tətbiq ön plana qayıtdıqda SIGCONT göndərilir və icra bərpa olunur. iOS-dan əsas fərq: App Freezer vəziyyətin qorunmasına zəmanət vermir — dondurma zamanı proses öldürülərsə, yaddaşdakı məlumatlar itirilə bilər.

Android-də SavedStateHandle-dən istifadə etmək tövsiyə olunur ViewModel-də hər hansı proses başa çatdıqda avtomatik vəziyyətin saxlanması üçün. SavedStateHandle məlumatları Bundle-də onSaveInstanceState vasitəsilə saxlayır, bu həm App Freezer, həm də Process Death-dən sağ çıxır. iOS-dan fərqli olaraq, burada Suspended-dən boşaltma müstəsna haldır, Android-də Process Death normal davranışdır və həmişə gözlənilməlidir.

kotlin
// SavedStateHandle — Android-də Process Death-dən qurtuluş
class CheckoutViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    // App Freezer-dən sonra da prosesdən sağ çıxacaq vəziyyət
    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
    }
}

// App Freezer halında onStop-da saxlama
class MainActivity : AppCompatActivity() {

    override fun onStop() {
        super.onStop()
        // Dondurmanı yaşamalı olan məlumatları saxlayırıq
        saveDraftData()
        // Dondurulmuş vəziyyətdə lazım olmayan resursları boşaldırıq
        releaseHeavyResources()
        // Tətbiqin dondurulacağı barədə xəbərdarlıq edirik
        // (Debug üçün jurnal)
        Log.d("Lifecycle", "Activity dayandırıldı — mümkün App Freeze")
    }
}

Kod Android-də Suspended analoqunun işlənməsi yanaşmasını göstərir. SavedStateHandle ViewModel-də Process Death zamanı avtomatik məlumatları saxlayır və bərpa edir. onStop — mümkün App Freezer və ya prosesin başa çatmasından əvvəl son zəmanətli hadisə. Sifariş formasının vəziyyəti, səbətdəki məhsulların siyahısı — bütün bu məlumatlar SavedStateHandle sayəsində dondurmadan sağ çıxır. Ağır resurslar üçün (bitmaplar, verilənlər bazası kursorları) onStop yaddaşı boşaltmaq yeridir.

State Restoration: Suspended-dən sonra bərpa

State Restoration — tətbiq yaddaşdan boşaldıldıqdan sonra UI vəziyyətinin saxlanması və bərpası üçün iOS-un daxili mexanizmidir. Əgər tətbiq Suspended-də idisə və sistem onu boşaltdısa, növbəti soyuq startda state restoration naviqasiya stack-ini, sürüşdürmə mövqeyini, forma vəziyyətini və digər UI elementlərini bərpa edir. İstifadəçi dayandığı ekrana qayıdır.

State Restoration UIViewControllerRestorationUIStateRestoring protokolları vasitəsilə işləyir. Tərtibatçı bərpa etmək istədiyi hər ViewController və View-ə restorationIdentifier təyin edir. Background-a keçərkən iOS bu obyektlərin vəziyyətini kodlaşdırır. Boşaltmadan sonra qayıtdıqda iOS yeni obyektlər yaradır və saxlanmış vəziyyəti dekodlaşdırır. State restoration olmadan istifadəçi dayandığı yerin əvəzinə soyuq startdan sonra boş ekran görəcək.

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
            // Məlumatların yüklənməsindən sonra mövqeni bərpa edirik
        }
    }
}

// AppDelegate — State Restoration-un aktivləşdirilməsi
func application(
    _ application: UIApplication,
    shouldSaveSecureApplicationState coder: NSCoder
) -> Bool {
    return true
}

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

Kod iOS-da State Restoration-un tətbiqini göstərir. restorationIdentifierrestorationClass hər bərpa olunan ViewController üçün lazımdır. encodeRestorableState/decodeRestorableState NSCoder vasitəsilə məlumatları saxlayır və yükləyir. AppDelegate-də shouldSaveSecureApplicationState və shouldRestoreSecureApplicationState şifrələnmiş vəziyyətin saxlanmasını aktivləşdirir. iOS 12+-dən verilənlərin qorunması üçün secure encoding (NSSecureCoding) tövsiyə olunur.

Suspended ilə iş üçün ən yaxşı təcrübələr

Birinci qayda — heç vaxt tətbiqin Suspended-dən qayıdacağını düşünməyin. Sistem istənilən anda tətbiqi boşalda bilər. Bütün kritik vacib məlumatlar Suspended-ə keçməzdən əvvəl — yəni applicationDidEnterBackground və ya onStop-da — davamlı yaddaşda saxlanmalıdır. UserDefaults, Core Data, File Manager — uyğun yaddaşlar. Yaddaş (dəyişənlər, xüsusiyyətlər) Suspended-dən sağ çıxmalı olan məlumatlar üçün etibarsız yaddaşdır.

İkinci qayda — Suspended-dən əvvəl resursları boşaldın. Fayl deskriptorlarını bağlayın, GPU yaddaşını (Metal, Core Graphics) boşaldın, şəbəkə birləşmələrini bağlayın. Tətbiq Suspended-də CPU istehlak etməsə də, tutulmuş resurslar digər tətbiqlər üçün bloklanır. iOS-da Suspended-də açıq soketlər saxlamaq olmaz — Suspended-dən qayıtdıqda onlar işlək olmaya bilər, bu səhvlərə səbəb olar.

Üçüncü qayda — Suspended-dən qayıtmağı gözləyən zamandan asılı məntiq yerləşdirməyin. Taymerlər, callback-lər və şəbəkə aktivliyi Suspended-də dayanır. Tətbiq bir neçə saat Suspended-də olubsa, qayıtdıqda taymer səhv işləyə bilər. Qayıtdıqda məlumatların aktuallığını yoxlayın — ola bilsin keş köhnəlib, avtorizasiya tokeni isə müddəti bitib.

Dördüncü qayda — bütün ekranlar üçün State Restoration-dan istifadə edin, xüsusilə daxiletmə formaları, sürüşdürülən siyahılar və detallı ekranlar üçün. State restoration olmadan, boşaldılmış Suspended-dən qayıtdıqdan sonra istifadəçi dayandığı yeri deyil, tətbiqin ilkin ekranını görəcək. Bu istifadəçi təcrübəsini pisləşdirir və onu hərəkətləri təkrarlamağa məcbur edir.

swift
import UIKit

// Yoxlama: tətbiq yaddaşdan boşaldılıbmı?
func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    // Saxlanmış vəziyyətin olub-olmadığını yoxlayırıq
    if UserDefaults.standard.object(forKey: "navStack") != nil {
        // Tətbiq Suspended-dən boşaldılıb
        // Vəziyyəti bərpa etmək lazımdır
        restoreNavigationStack()
    } else {
        // Not Running-dən təmiz soyuq start
        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)
        }
    }
}

Kod tətbiqin Suspended-dən boşaldılıb-boşaldılmadığını müəyyən etmək təcrübəsini göstərir. UserDefaults-ın yoxlanması saxlanmış naviqasiya stack-inin mövcudluğuna görə boşaltmadan sonra soyuq startı təmiz soyuq startdan ayırmağa imkan verir. Birinci halda naviqasiya stack-i bərpa olunur, ikincidə — onboarding və ya əsas ekran göstərilir. Bu yanaşma NSCoder-in kifayət etmədiyi hallarda daxili State Restoration-u tamamlayır.

Tez-tez verilən suallar

Tətbiq Suspended-də nə qədər qala bilər?

Məhdudiyyətsiz — bir neçə saniyədən bir neçə günə qədər. iOS-da Suspended üçün vaxt aşımı yoxdur. Tətbiq sistem resurs çatışmazlığı səbəbindən onu boşaltmaq qərarına gələnə qədər yaddaşda qalacaq. Praktikada tətbiqlər cihazın operativ yaddaşının həcmindən və aktiv tətbiqlərin sayından asılı olaraq 15 dəqiqədən bir neçə saata qədər Suspended-də qalır.

Suspended-dən boşaltma zamanı applicationWillTerminate çağırılırmı?

Xeyr. applicationWillTerminate çağırılmır tətbiq Suspended-dən boşaldıldıqda. Sistem sadəcə tətbiqə bildiriş vermədən yaddaşı boşaldır. Bu, bütün məlumatların saxlanmasının applicationDidEnterBackground-da baş verməsinin daha bir səbəbidir. applicationWillTerminate yalnız istifadəçi tətbiqi App Switcher-dən sürüşdürərək əl ilə başa çatdırdıqda çağırılır.

Android-in Suspended analoqu varmı?

Birbaşa analoqu yoxdur. Android 11+-də App Freezer meydana çıxdı, o SIGSTOP vasitəsilə fon proseslərini dayandırır — bu funksional olaraq Suspended-ə bənzəyir. Lakin Android tətbiqləri istənilən anda Process Death-ə hesablanaraq layihələndirilməlidir. ViewModel-də SavedStateHandle və onSaveInstanceState-dən istifadə edin ki, vəziyyət həm App Freezer, həm də Process Death-dən sağ çıxsın.

Tətbiqin Suspended-də olduğunu necə yoxlamaq olar?

iOS-da birbaşa yoxlama API-i yoxdur. Dolayı metod: UserDefaults-ı yoxlayın didFinishLaunchingWithOptions-da saxlanmış vəziyyətin mövcudluğuna görə. Vəziyyət varsa — tətbiq Suspended-dən boşaldılıb və soyuq start edir. Vəziyyət yoxdursa — təmiz soyuq start. SwiftUI-də scenePhase.background-da flag saxlaya və növbəti işə salmada yoxlaya bilərsiniz.

Suspended kontekstində snapshot nədir?

Suspended-ə keçərkən iOS snapshot — tətbiqin cari UI-nin ekran görüntüsünü çəkir. Bu görüntü App Switcher-də və tətbiqə qayıtdıqda (ərimə animasiyası kimi) göstərilir. Tətbiq məxfi məlumatlar ehtiva edirsə, snapshot onları aşkar edə bilər. Qoruma üçün UIApplication.shouldSnapshotSecureApp (iOS 16+) istifadə edin və ya applicationDidEnterBackground-da blur-overlay tətbiq edin.

Nəticə

  • Suspended — tətbiq iOS yaddaşında dondurulub, kod icra olunmur, lakin UI-stack ani bərpa üçün qorunur
  • iOS-un unikallığı — Suspended Android-də yoxdur; Android qismən analoq kimi App Freezer (SIGSTOP) istifadə edir
  • Boşaltma — sistem Suspended tətbiqləri bildirişsiz, yaddaş çatışmazlığında ilk növbədə boşaldır
  • Saxlama — applicationDidEnterBackground — son zəmanətli metod, bütün məlumatlar burada saxlanmalıdır
  • State Restoration — Suspended-dən boşaltmadan sonra UI-nin avtomatik bərpası üçün NSCoder mexanizmi
  • Android alternativi — SavedStateHandle + onSaveInstanceState Process Death-dən sağ çıxmaq üçün
  • Snapshot — iOS Suspended zamanı ekran görüntüsü çəkir; məxfi məlumatlar blur-overlay və ya secure snapshot ilə gizlədilməlidir

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun