ARC: nedir, iOS'ta Automatic Reference Counting'in çalışma prensibi

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

Automatic Reference Counting (ARC), Swift ve Objective-C'de her nesneye yapılan referans sayısını otomatik olarak sayan ve sayaç sıfıra ulaştığında nesneyi serbest bırakan bir bellek yönetim sistemidir. Apple Swift Belgeleri, 2026'ya göre ARC, derleyiciye gömülüdür ve derleme zamanında çalışarak uygun yerlere retain/release çağrıları ekler. Garbage Collection'ın aksine ARC, ayrı bir toplayıcı iş parçacığı gerektirmez ve uygulama çalışması sırasında duraklamalar oluşturmaz.

Önemli Noktalar

  • ARC — Automatic Reference Counting, Swift ve Objective-C'de derleyici tabanlı bellek yönetim sistemi
  • Çalışma prensibi — her nesnenin bir referans sayacı (retain count) vardır; sıfırlandığında nesne hemen serbest bırakılır
  • Niteleyiciler — strong, weak ve unowned, referansın sayacı ve nesnenin yaşam döngüsünü nasıl etkilediğini belirler
  • GC'den farkı — ARC derleme zamanında deterministik olarak çalışır, Stop-The-World duraklamaları veya arka plan toplayıcı iş parçacığı olmadan
  • Retain Cycle — ARC'nin ana sorunu: iki nesne strong aracılığıyla birbirini referans alırsa, sayaçları asla sıfırlanmaz

ARC nedir?

ARC (Automatic Reference Counting), Apple tarafından Xcode 4.2'de (2011) Objective-C için tanıtılan ve Swift tarafından miras alınan derleyici tabanlı bir bellek yönetim mekanizmasıdır. Manuel bellek yönetiminden (Manual Retain-Release, MRR) farklı olarak ARC, retain, release ve autorelease çağrılarını tamamen otomatikleştirir ve geliştirici müdahalesi olmadan derleme zamanında ekler.

ARC bir çöp toplayıcı değildir. Dinamik kod ekleme ile statik analizdir: derleyici nesne ömürlerini analiz eder ve nesnelerin oluşturulduğu, kopyalandığı veya kapsam dışına çıktığı noktalara retain/release yerleştirir. Sonuç deterministik bellek serbest bırakmadır: nesne, ona işaret eden hiçbir referans kalmadığında, gecikme veya duraklama olmadan tam olarak o anda silinir.

WWDC 2011 Session 323'e göre, MRR'den ARC'ye geçiş, Apple uygulamalarındaki bellek ile ilgili çökme hatalarını %70 oranında azaltmıştır. Geliştiriciler manuel olarak retain/release dengesi kurmayı bırakmış, bu da bir bütün sızıntı ve double-free hatası sınıfını ortadan kaldırmıştır.

Automatic Reference Counting nasıl çalışır

Bellekteki her nesnenin bir referans sayacı (retain count) vardır. Bir nesne oluşturulduğunda sayaç 1 olarak ayarlanır. Yeni bir strong referans nesneyi işaret ettiğinde sayaç artar (retain). Bir strong referans kaybolduğunda sayaç azalır (release). Sıfıra ulaştığında nesne hemen serbest bırakılır.

Swift derleyicisi her atamada retain/release eklemez — optimizasyon için statik analiz kullanır. Örneğin, bir nesnenin aktarıldıktan sonra kullanılmayacağı garanti edilirse, derleyici gereksiz bir release/retain'i atlayabilir. Bu optimizasyona ARC Optimization denir.

swift
class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) initialized (retain count: 1)")
    }
    deinit {
        print("\(name) deallocated")
    }
}

func testARC() {
    let p = Person(name: "Alice")  // retain count = 1
    let q = p                      // retain count = 2
    // q kapsam dışına çıkar
    // retain count = 1
    // p kapsam dışına çıkar
    // retain count = 0 → deinit
}

Bu örnek, ARC'nin sayacı nasıl yönettiğini gösterir: q = p atandığında sayaç artar; q kapsam dışına çıktığında azalır. Son strong referans kaybolduğunda, yıkıcı hemen çağrılır. Hiçbir çöp toplayıcı beklemez — bellek anında serbest bırakılır.

ARC vs Garbage Collection: temel farklar

ARC ve Garbage Collection aynı sorunu — otomatik bellek yönetimini — ancak temelde farklı yaklaşımlarla çözer. Aralarındaki seçim dil mimarisini belirler: Swift (ARC) vs Java/Go (GC). Temel farklara bakalım.

ÖzellikARC (Swift/ObjC)GC (Java/Go)
Serbest bırakma zamanıDeterministik: sayaç sıfırlandığında hemenDeterministik olmayan: sonraki toplama döngüsünde
Yürütme duraklamalarıYok (retain/release derleme zamanında eklenir)Stop-The-World duraklamaları (2–200 ms)
Ek yükHer referansta sayaç artırma/azaltmaNesne grafiği gezinme, işaretleme, temizleme
SorunlarRetain Cycle (manuel çözüm)Yığın parçalanması, unutulan referanslardan sızıntılar
Ek iş parçacığıGerekmezÇöp toplayıcı iş parçacığı gerekir

Temel ödünleşim: ARC öngörülebilir nesne ömürleri ve sıfır duraklama sağlar, ancak geliştiricinin retain cycle'ları anlamasını ve weak/unowned'ı doğru seçmesini gerektirir. GC, geliştiriciyi bu endişelerden kurtarır, ancak deterministik olmayan duraklamalar ve ek bir iş parçacığı pahasına.

Strong, Weak ve Unowned: ARC'de referans niteleyicileri

ARC, her biri sayacı ve nesne yaşam döngüsünü farklı şekilde etkileyen üç tür referans niteleyicisi tanımlar. Doğru niteleyiciyi seçmek, Swift'te güvenli bellek yönetiminin temelidir.

Strong

Strong varsayılan niteleyicidir. Her strong referans, nesnenin retain count'unu 1 artırır. En az bir strong referans var olduğu sürece nesne canlı kalır. Swift'teki tüm sınıf özellikleri ve yerel değişkenler varsayılan olarak strong'dur. Strong referanslar bir sahiplik ilişkisi oluşturur: A nesnesi B nesnesine sahiptir.

Weak

Weak, retain count'u artırmayan bir referanstır. Bir weak referans nesneyi işaret etse bile nesne serbest bırakılabilir. Serbest bırakıldıktan sonra weak referans otomatik olarak nil olarak ayarlanır. Weak referanslar her zaman var olarak isteğe bağlı türle (?) bildirilir. Özellikle delegate deseninde retain cycle'ları kırmak için kullanılır.

Unowned

Unowned, weak gibi retain count'u artırmayan sahip olmayan bir referanstır. Ancak, unowned referans serbest bırakıldıktan sonra nil olarak ayarlanmaz — serbest bırakılmış bir nesneye erişmek çökmeye neden olur. Unowned, nesnenin en az referans alan nesne kadar yaşayacağı garanti edildiğinde kullanılır. Tipik kullanım durumları closure'lar ve garantili yaşam süresine sahip ebeveyn-çocuk ilişkileridir.

swift
class Customer {
    let name: String
    var card: CreditCard?         // strong
    init(name: String) { self.name = name }
    deinit { print("\(name) deallocated") }
}

class CreditCard {
    let number: String
    unowned let customer: Customer   // unowned — sahip değil
    init(number: String, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit { print("Card \(number) deallocated") }
}

var customer: Customer? = Customer(name: "Bob")
customer?.card = CreditCard(number: "1234", customer: customer!)
customer = nil
// Customer ve CreditCard ikisi de serbest bırakıldı — retain cycle yok

Burada CreditCard, Customer'a unowned referans kullanır. Customer karta sahiptir (strong), ve kart müşteriye sahip değildir (unowned). Customer serbest bırakıldığında, her iki nesne de serbest bırakılır — retain cycle oluşmaz. card.customer strong olsaydı, döngü serbest bırakmayı engellerdi.

ARC'nin yaygın sorunları ve çözümleri

Otomasyona rağmen ARC her derde deva değildir. Geliştiriciler, iç bellek yönetim mekanizmasını anlamayı gerektiren birkaç tipik sorunla karşılaşır.

Closure'larda Retain Cycle

Swift'teki closure'lar dış değişkenleri strong referansla yakalar. Bir closure bir sınıf özelliğine atanır ve self'i yakalarsa, bir retain cycle oluşur: sınıf closure'ı tutar, closure self'i tutar. Çözüm, weak veya unowned ile bir yakalama listesidir.

swift
class NetworkManager {
    var completionHandler: ((Data?) -> Void)?
    var data: Data?

    func fetchData() {
        completionHandler = { [weak self] result in
            guard let self else { return }
            self.data = result
            self.processResult()
        }
    }

    func processResult() { }
}

Yakalama listesi [weak self], closure içinde self'e weak bir referans oluşturur. Bu, potansiyel retain cycle'ı kırar. Guard let self, kodu çalıştırmadan önce nesnenin canlı olduğunu garanti eder. weak self, Swift'teki asenkron closure'lar için standart uygulamadır.

Retain/Release Performansı

Retain/release hafif işlemler olsa da, sıcak döngülerde sık sayaç artırma/azaltma ek yük ekler. Swift 5.9+'da derleyici, analizcinin güvenli olduğunu kanıtlaması durumunda gereksiz retain/release'leri kaldıran bir optimizasyon kullanır. Ancak Objective-C'de, retain/release saniyede milyonlarca çağrı içeren yüksek yük senaryolarında hala darboğaz olabilir.

Autorelease Pool

Autorelease Pool, Objective-C ve bazı Swift senaryolarında kullanılan ertelenmiş bir serbest bırakma mekanizmasıdır. Nesneler havuza yerleştirilir ve havuz boşaltıldığında release alır. Çok sayıda geçici nesne içeren döngülerde (örneğin JSON ayrıştırma), özel bir autoreleasepool oluşturmak, pik bellek tüketimini azaltır.

Sıkça Sorulan Sorular

ARC, manuel bellek yönetiminden (MRR) nasıl farklıdır?

Manuel yönetimde (MRR), geliştirici açıkça retain, release ve autorelease çağırırdı. ARC bu çağrıları derleme zamanında otomatik olarak ekler, double-free riskini, unutulan release'den kaynaklanan sızıntıları ve retain/release dengesi hatalarını ortadan kaldırır.

ARC, C/C++ koduyla çalışabilir mi?

ARC yalnızca Objective-C nesnelerini ve Swift sınıflarını yönetir. C/C++ yapıları ve işaretçileri için ARC uygulanmaz — bu nesneler manuel olarak veya C++ akıllı işaretçileri (shared_ptr, unique_ptr) aracılığıyla yönetilir. Core Foundation nesneleri (CFString, CGColor) da ARC kapsamında değildir.

Ne zaman weak, ne zaman unowned kullanılır?

weak — nesne, referans alan nesneden önce serbest bırakılabildiğinde (temsilciler, asenkron closure'lar). unowned — nesnenin en az referans alan nesne kadar yaşayacağı garanti edildiğinde (çocuğun ebeveyn olmadan var olamayacağı ebeveyn-çocuk). Emin değilseniz weak seçin.

Varoluşsal türler (Existential Types) nedir ve ARC'yi nasıl etkiler?

Swift'teki varoluşsal türler (protokol tür olarak), değeri özel bir kapsayıcıya (existential container) sarar. Bu, protokol sınırlarında retain/release sayısını artırır. Swift 5.7+'da, opak sonuç türleri ve some parametreleri, kapsayıcıyı ortadan kaldırarak ek yükü azaltır.

Swift'te retain count nasıl kontrol edilir?

Swift'te retain count'u okumak için doğrudan bir API yoktur — bu bir uygulama detayı olarak kabul edilir. Teşhis için Xcode'da Instruments (Allocations, Leaks) veya Bellek Hata Ayıklayıcısı'nı kullanın. Bu araçlar, canlı sınıf örneklerinin sayısını ve tutma zincirlerini gösterir.

Özet

  • ARC — referans sayımı yoluyla çalışan, Swift ve Objective-C için derleyici tabanlı bellek yönetim sistemi
  • İlke — her nesnenin retain count'u vardır; sıfırlandığında nesne hemen ve deterministik olarak serbest bırakılır
  • GC'den farkı — ARC arka plan iş parçacığı veya Stop-The-World duraklamaları olmadan çalışır, ancak retain cycle kontrolü gerektirir
  • Strong — sayacı artırır; weak ve unowned artırmaz, ancak unowned serbest bırakıldığında nil olmaz
  • Closure'lar — Swift'te retain cycle'ların ana nedeni; [weak self] yakalama listesi standart çözümdür
  • Autorelease Pool — döngülerdeki ve özel senaryolardaki geçici nesneler için ertelenmiş serbest bırakma mekanizması
  • Teşhis — Xcode Bellek Hata Ayıklayıcısı, Instruments ve LeakCanary (ObjC köprüsü aracılığıyla) sorunları bulmak için

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