Suspended — nedir, iOS arka planında uygulama dondurma

Yazar: IT Sectr Yayınlanma: 2026-03-03 Okuma süresi: 11 dk

Suspended — iOS uygulama yaşam döngüsünün askıya alınmış bir durumudur; uygulama bellekte dondurulur ancak kod çalıştırmaz. Suspended'ın nasıl çalıştığını, arka planda uygulama dondurmanın getirdiği riskleri, iOS'un Suspended uygulamaların boşaltılmasını nasıl yönettiğini ve Suspended'den döndükten sonra kesintisiz kurtarma için state restoration'ın nasıl uygulanacağını gösteriyoruz.

Temel Noktalar

  • Suspended — uygulama bellekte dondurulur, kod çalıştırılmaz, UI yığını korunur
  • iOS Suspended — Android'de olmayan benzersiz bir durum; süreç var ancak aktif değil
  • Boşaltma — bellek azaldığında Suspended uygulamalar önce kaldırılır, bellekteki veriler kaybolur
  • State Restoration — boşaltma sonrası UI yığınını kaydetmek ve geri yüklemek için iOS mekanizması
  • didEnterBackground — Suspended'den önce çağrılması garanti edilen son yöntem

Suspended — bu durum nedir

Suspended, iOS uygulama yaşam döngüsünün bir durumudur; uygulama cihazın RAM'inde bulunur ancak hiçbir kod çalıştırmaz. Bu, tam sonlandırmadan önceki son durumdur: uygulama, tüm arka plan görevlerini tamamladıktan veya bir zaman aşımı süresi dolduktan sonra Background'dan Suspended'e geçer. Suspended'de uygulama tamamen dondurulur — tüm iş parçacıkları durdurulur, zamanlayıcılar çalışmaz ve ağ etkinliği olmaz.

Suspended, iOS'un benzersiz bir özelliğidir ve standart Android yaşam döngüsünde bulunmaz. Bunun nedeni, farklı süreç yönetim mimarileridir. iOS, uygulamanın görüntüsünü bellekte korur (masaüstü hazırda bekletmeye benzer), böylece kullanıcı geri döndüğünde arayüz soğuk başlatma olmadan anında geri yüklenebilir. Android'de Suspended yoktur — bir süreç ya var olur ve kod çalıştırabilir (Background) ya da sonlandırılır (Not Running), ancak Android LMK aracılığıyla iş parçacığı yürütmesini durdurabilir.

Kullanıcı için Suspended, anında geri yükleme gibi görünür: App Switcher aracılığıyla uygulamalar arasında geçiş yaparlar ve her uygulama bıraktıkları yerden açılır. Bu, tüm uygulamaların aynı anda çalıştığı yanılsamasını yaratır. Gerçekte, çoğu Suspended'de dondurulmuştur. Suspended'den sıcak başlatma, Not Running'dan soğuk başlatmaya göre kat kat daha hızlıdır, çünkü kod zaten belleğe yüklenmiştir.

Sistem Suspended'i nasıl yönetir

iOS, tüm uygulamaların durumunu izler ve kullanılabilir belleğe göre Suspended uygulamaları boşaltmaya karar verir. Bellek azaldığında, sistem Suspended uygulamaları boşaltmaya başlar, en uzun süre bu durumda olanlardan başlayarak. Bellek hala yetersizse, sistem Background ve Inactive'deki uygulamaları Suspended'e geçirir ve ardından boşaltır. Bu süreç kullanıcı için tamamen şeffaftır — kullanıcı App Switcher'da uygulama simgesini görür ve dokunduğunda soğuk başlatma başlatır.

ÖzellikSuspended (iOS)Background (iOS)Background (Android)
Kod çalıştırırHayırEvet (sınırlı)Evet (sınırlı)
BellekteEvetEvetEvet
CPU tüketimi%0DüşükDüşük
Sıcak başlatmaEvet — anında geri yüklemeEvet — Inactive aracılığıylaHayır — süreç sonlandırılmış olabilir
Zaman aşımıHayır — saatlerce bellekte kalabilir~30 saniye (beginBackgroundTask sonrası)API sürümüne bağlı
Sistem tarafından boşaltmaBellek azaldığındaBellek kritik derecede azaldığındaLMK (Low Memory Killer)
İşe dönüşApp Switcher'dan — anındaApp Switcher'dan — Inactive aracılığıylaSoğuk başlatma
State RestorationÖnerilirGerekli değilSavedStateHandle

iOS'ta Suspended: dondurma mekanizması

iOS'ta, tüm arka plan görevleri tamamlandıktan sonra Suspended otomatik olarak ulaşılır. Sistem applicationDidEnterBackground'ı çağırır, beginBackgroundTask'ı yürütmek için zaman verir (yaklaşık 30 saniye), ardından tüm iş parçacıklarını zorla durdurur ve uygulamayı Suspended'e geçirir. Bellekteki nesneler korunur, ancak hiçbir kod çalıştırılmaz — uygulama mevcut durumunda dondurulur.

Kritik derecede önemli bir nokta: applicationDidEnterBackground, Suspended'den önce çağrılması garanti edilen son yöntemdir. Bundan sonra uygulama, bellek boşaltma hakkında herhangi bir bildirim almaz. Kullanıcı veya sistem Suspended'deki uygulamayı sonlandırırsa, ne applicationWillTerminate ne de applicationDidEnterBackground yeniden çağrılır. Bu nedenle, tüm veri kaydetme işlemi applicationDidEnterBackground'da gerçekleşmelidir, applicationWillTerminate'te değil.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Suspended'den önce son garantili çağrı
    func applicationDidEnterBackground(_ application: UIApplication) {
        // Bellek boşaltmadan kurtulması gereken her şeyi kaydet
        savePersistentState()
        saveNavigationStack()

        // Gerekirse ek süre iste
        let task = application.beginBackgroundTask {
            application.endBackgroundTask(task)
        }
    }

    // Suspended'den dönüş — sıcak başlatma
    func applicationWillEnterForeground(_ application: UIApplication) {
        // Uygulama Suspended'deydi, çalışmaya devam
        print("Suspended veya Background'dan dönüş")
    }

    // Bellek boşaltma sonrası tam kurtarma
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Bu, Suspended'den boşaltma sonrası soğuk başlatma ise —
        // state restoration'ı geri yükle
        return true
    }

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

    private func saveNavigationStack() {
        guard let rootVC = window?.rootViewController else { return }
        // Mevcut gezinme yığınını kaydet
        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'ta Suspended'in kritik derecede önemli işlenmesini gösterir. applicationDidEnterBackground son garantili çağrıdır. Tüm veri kaydetme burada gerçekleşmelidir: kullanıcı durumu, gezinme yığını, taslaklar, zamanlayıcılar. applicationWillEnterForeground, Suspended veya Background'dan dönüşte çağrılır. didFinishLaunchingWithOptions — yalnızca uygulama Suspended sonrası bellekten boşaltıldığında soğuk başlatmada çağrılır.

Android'de Suspended — bir benzeri var mı

Android'de, iOS Suspended'in doğrudan bir benzeri yoktur. Android, yürütme bağlamını koruyarak uygulamaları bellekte dondurmaz. Bunun yerine, Android süreci arka planda tutar veya sonlandırır. Ancak, Android 11+ (API 30) üzerinde App Freezer adlı bir mekanizma tanıtılmıştır ve SIGSTOP sinyalini kullanarak arka plan süreçlerinin yürütmesini durdurur. Bu, işlevsel olarak Suspended'e benzer, ancak önemli farklılıklar vardır.

App Freezer, Android bellek yönetim sisteminin bir parçasıdır. Bir uygulama aktif bildirim olmadan uzun süre arka planda kaldığında, sistem SIGSTOP gönderir ve tüm iş parçacıklarını durdurur. Uygulama ön plana döndüğünde SIGCONT gönderilir ve yürütme devam eder. iOS'tan temel fark: App Freezer durum korumasını garanti etmez — dondurma sırasında süreç sonlandırılırsa bellekteki veriler kaybolabilir.

Android'de, herhangi bir süreç sonlandırmasında otomatik durum koruması için ViewModel'de SavedStateHandle kullanılması önerilir. SavedStateHandle, onSaveInstanceState aracılığıyla bir Bundle'da veri kaydeder ve hem App Freezer'dan hem de Process Death'ten kurtulur. iOS'un aksine, Suspended'den boşaltmanın istisnai bir durum olduğu iOS'ta, Android'de Process Death her zaman beklenmesi gereken normal bir davranıştır.

kotlin
// SavedStateHandle — Android'de Process Death'ten kurtuluş
class CheckoutViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    // App Freezer'dan sonra bile süreci atlatan durum
    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 durumunda onStop'a kaydet
class MainActivity : AppCompatActivity() {

    override fun onStop() {
        super.onStop()
        // Dondurmadan kurtulması gereken verileri kaydet
        saveDraftData()
        // Dondurulmuş durumda gerekli olmayan kaynakları serbest bırak
        releaseHeavyResources()
        // Uygulamanın dondurulacağını bildir
        // (Hata ayıklama için günlük kaydı)
        Log.d("Lifecycle", "Activity stopped — olası App Freeze")
    }
}

Kod, Android'de Suspended benzerini işleme yaklaşımını gösterir. ViewModel'deki SavedStateHandle, Process Death sırasında verileri otomatik olarak kaydeder ve geri yükler. onStop, olası bir App Freezer veya süreç sonlandırmasından önceki son garantili olaydır. Ödeme formu durumu, sepetteki ürün listesi — tüm bu veriler, SavedStateHandle sayesinde dondurmadan kurtulur. Ağır kaynaklar (bitmap'ler, DB imleçleri) için onStop, belleği serbest bırakma yeridir.

State Restoration: Suspended sonrası kurtarma

State Restoration, uygulama bellekten boşaltıldıktan sonra UI durumunu kaydetmek ve geri yüklemek için yerleşik bir iOS mekanizmasıdır. Uygulama Suspended'deyse ve sistem onu boşalttıysa, bir sonraki soğuk başlatmada state restoration gezinme yığınını, kaydırma konumunu, form durumunu ve diğer UI öğelerini geri yükler. Kullanıcı kaldığı yere geri döner.

State Restoration, UIViewControllerRestoration ve UIStateRestoring protokolleri aracılığıyla çalışır. Geliştirici, geri yüklemek istediği her ViewController ve View'e bir restorationIdentifier atar. Arka plana gidildiğinde, iOS bu nesnelerin durumunu kodlar. Boşaltma sonrası geri dönüşte, iOS yeni nesneler oluşturur ve kaydedilen durumu çözer. State restoration olmadan, kullanıcı soğuk başlatma sonrası kaldığı yer yerine boş bir ekran görür.

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
            // Veri yükleme sonrası konumu geri yükle
        }
    }
}

// AppDelegate — State Restoration'ı etkinleştirme
func application(
    _ application: UIApplication,
    shouldSaveSecureApplicationState coder: NSCoder
) -> Bool {
    return true
}

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

Kod, iOS'ta State Restoration'ın uygulanmasını gösterir. Geri yüklenebilir her ViewController için restorationIdentifier ve restorationClass gereklidir. encodeRestorableState/decodeRestorableState, NSCoder aracılığıyla verileri kaydeder ve yükler. AppDelegate'te, shouldSaveSecureApplicationState ve shouldRestoreSecureApplicationState şifreli durum kaydetmeyi etkinleştirir. iOS 12+ üzerinde, veri koruması için güvenli kodlama (NSSecureCoding) kullanılması önerilir.

Suspended ile çalışmak için en iyi uygulamalar

Birinci kural — uygulamanın Suspended'den döneceğini asla varsaymayın. Sistem uygulamayı her an boşaltabilir. Tüm kritik derecede önemli veriler, Suspended'e geçişten önce kalıcı depolamaya kaydedilmelidir — yani applicationDidEnterBackground veya onStop'da. UserDefaults, Core Data, File Manager — uygun depolama seçenekleri. Bellek (değişkenler, özellikler), Suspended'den kurtulması gereken veriler için güvenilmez bir depolamadır.

İkinci kural — Suspended'den önce kaynakları serbest bırakın. Dosya tanımlayıcıları kapatın, GPU belleğini (Metal, Core Graphics) serbest bırakın, ağ bağlantılarını kapatın. Uygulama Suspended'de CPU tüketmese de, tutulan kaynaklar diğer uygulamalar için bloke edilir. iOS'ta, Suspended'de açık soket tutulamaz — Suspended'den dönüşte çalışmayabilir ve hatalara neden olabilir.

Üçüncü kural — Suspended'den dönüşü bekleyen zamana bağımlı mantık yerleştirmeyin. Zamanlayıcılar, geri çağırmalar ve ağ etkinliği Suspended'de durur. Uygulama birkaç saat Suspended'de kaldıysa, dönüşte bir zamanlayıcı yanlış çalışabilir. Dönüşte veri geçerliliğini kontrol edin — önbellek güncelliğini yitirmiş olabilir ve yetkilendirme belirtecinin süresi dolmuş olabilir.

Dördüncü kural — tüm ekranlar için State Restoration kullanın, özellikle giriş formları, kaydırılabilir listeler ve detay ekranları için. State restoration olmadan, boşaltılmış bir Suspended'den döndükten sonra kullanıcı, kaldığı yer yerine uygulamanın başlangıç ekranını görür. Bu, kullanıcı deneyimini kötüleştirir ve kullanıcıyı eylemleri tekrarlamaya zorlar.

swift
import UIKit

// Kontrol: uygulama bellekten boşaltıldı mı?
func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    // Kaydedilmiş durum olup olmadığını kontrol et
    if UserDefaults.standard.object(forKey: "navStack") != nil {
        // Uygulama Suspended'den boşaltıldı
        // Durumu geri yüklemeli
        restoreNavigationStack()
    } else {
        // Not Running'dan temiz soğuk başlatma
        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, uygulamanın Suspended'den boşaltılıp boşaltılmadığını belirleme uygulamasını gösterir. Kaydedilmiş bir gezinme yığınının varlığı için UserDefaults'ı kontrol etme, boşaltma sonrası soğuk başlatmayı temiz soğuk başlatmadan ayırt etmeyi sağlar. İlk durumda, gezinme yığını geri yüklenir; ikincisinde, tanıtım veya ana ekran gösterilir. Bu yaklaşım, NSCoder'ın yetersiz olduğu durumlar için yerleşik State Restoration'ı tamamlar.

Sıkça Sorulan Sorular

Bir uygulama Suspended'de ne kadar kalabilir?

Sınırsız — birkaç saniyeden birkaç güne kadar. iOS'un Suspended için zaman aşımı yoktur. Uygulama, sistem kaynak yetersizliği nedeniyle boşaltmaya karar verene kadar bellekte kalır. Uygulamada, uygulamalar cihazın RAM'ine ve aktif uygulama sayısına bağlı olarak 15 dakikadan birkaç saate kadar Suspended'de kalır.

Suspended'den boşaltırken applicationWillTerminate çağrılır mı?

Hayır. Uygulama Suspended'den boşaltıldığında applicationWillTerminate çağrılmaz. Sistem, uygulamayı bilgilendirmeden belleği basitçe serbest bırakır. Bu, tüm veri kaydetmenin applicationDidEnterBackground'da gerçekleşmesi gerektiğinin bir başka nedenidir. applicationWillTerminate yalnızca kullanıcı uygulamayı App Switcher'dan kaydırarak manuel olarak sonlandırdığında çağrılır.

Android'in Suspended benzeri var mı?

Doğrudan bir benzeri yoktur. Android 11+ üzerinde, arka plan süreçlerini SIGSTOP aracılığıyla durduran App Freezer tanıtılmıştır — bu işlevsel olarak Suspended'e benzer. Ancak, Android uygulamaları her an Process Death olabileceğini varsayarak tasarlanmalıdır. Hem App Freezer'dan hem de Process Death'ten kurtulacak durumu kaydetmek için ViewModel'de SavedStateHandle ve onSaveInstanceState kullanın.

Uygulamanın Suspended'de olup olmadığını nasıl kontrol ederim?

iOS'ta kontrol etmek için doğrudan bir API yoktur. Dolaylı bir yöntem: didFinishLaunchingWithOptions'ta kaydedilmiş durumun varlığı için UserDefaults'ı kontrol edin. Durum varsa — uygulama Suspended'den boşaltılmış ve soğuk başlatma yapıyor. Durum yoksa — temiz bir soğuk başlatmadır. SwiftUI'de, scenePhase.background'a bir işaret kaydedilebilir ve bir sonraki başlatmada kontrol edilebilir.

Suspended bağlamında anlık görüntü (snapshot) nedir?

Suspended'e geçiş yaparken, iOS bir anlık görüntü — mevcut uygulama UI'ının ekran görüntüsünü çeker. Bu ekran görüntüsü App Switcher'da ve uygulamaya dönüşte (“çözülme” animasyonu olarak) gösterilir. Uygulama gizli veriler içeriyorsa, anlık görüntü bunları açığa çıkarabilir. Korumak için UIApplication.shouldSnapshotSecureApp (iOS 16+) kullanın veya applicationDidEnterBackground'da bir bulanıklık katmanı uygulayın.

Özet

  • Suspended — uygulama iOS belleğinde dondurulur, kod çalıştırılmaz, ancak anında geri yükleme için UI yığını korunur
  • iOS benzersizliği — Suspended Android'de yoktur; Android kısmi benzer olarak App Freezer (SIGSTOP) kullanır
  • Boşaltma — sistem, bellek azaldığında Suspended uygulamaları ilk öncelik olarak bildirim yapmadan boşaltır
  • Kaydetme — applicationDidEnterBackground son garantili yöntemdir; tüm veriler burada kaydedilmelidir
  • State Restoration — Suspended'den boşaltma sonrası otomatik UI geri yükleme için NSCoder tabanlı mekanizma
  • Android alternatifi — Process Death'ten kurtulmak için SavedStateHandle + onSaveInstanceState
  • Anlık görüntü — iOS Suspended sırasında ekran görüntüsü çeker; gizli veriler bulanıklık katmanı veya güvenli anlık görüntü ile gizlenmelidir

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun