Swift’te ARC (Automatic Reference Counting) ile Bellek Yönetimi
Swift, C veya C++ gibi dillerin aksine, geliştiriciden doğrudan hafıza yönetimi yapmasını beklemez. Ancak bu rahatlık, bazen büyük…
Swift’te ARC (Automatic Reference Counting) ile Bellek Yönetimi

Bunun ARC olduğunu düşünebilirsiniz :)
Swift, C veya C++ gibi dillerin aksine, geliştiriciden doğrudan hafıza yönetimi yapmasını beklemez. Ancak bu rahatlık, bazen büyük sorunlara da yol açabiliyor. Ben de ilk “retain cycle” hatamı aldığımda ARC’nin aslında ne kadar önemli olduğunu fark ettim.
ARC Nedir ?
Automatic Reference Counting (ARC), Swift’te referans tiplerinin (class) bellekte ne zaman oluşturulacağı ve yok edileceğini kontrol eden bir sistemdir.
- Her class türü nesne oluşturulduğunda, ARC ona bir referans sayacı atar.
- Başka bir referans, bu nesneyi tuttuğunda sayaç 1 artar.
- Referans kaldırıldığında sayaç azalır.
- Sayaç 0 olduğunda, ARC nesneyi bellekten siler (
deinitçağrılır).
class Person {
let name: String
init(name: String) {
self.name = name
print("\(name) init")
}
deinit {
print("\(name) deinit")
}
}
var person1: Person? = Person(name: "UK") // referans sayısı 1 artar => 1
var person2 = person1 // referans sayısı 2
person1 = nil // referans sayısı 1
person2 = nil // referans sayısı 0 → deinit çağrılır
Bu örnekte her şey kontrol altında. Ancak işin içine closure, delegate gibi yapılar girdiğinde işler karmaşıklaşıyor.
Strong ve Weak Referans Nedir?
Swift’te ARC sistemi her referansı aynı şekilde değerlendirmez. Referans tiplerinin bellekte nasıl tutulacağını belirlemek için strong, weak, ve unowned gibi referans türleri kullanırız. ARC’nin nasıl çalıştığını anlamak için özellikle strong ve weak farkını bilmek kritiktir.
Strong Referans (varsayılan)
- Her değişken varsayılan olarak bir nesneyi strong referansla tutar.
- Bu, ARC sayacını 1 artırır.
var a = MyClass()
var b = a // b de strong referans
Bu yüzden a ve b nil olmadan nesne bellekten atılamaz.
a = nil // referans sayısı 1
b = nil // referans sayısı 0 → deinit çağrılır
Weak Referans
- ARC sayacını artırmaz.
- Nesne silindiğinde otomatik olarak
nilolur. - Bu yüzden sadece opsiyonel (
?) olarak tanımlanabilir.
class Owner {
var pet: Pet?
}
class Pet {
weak var owner: Owner? // ← strong yerine weak referans
}
Burada:
Owner→Petstrong tutar.Pet→Ownerweak tuttuğu için ARC sayacını artırmaz.- İki sınıf birbirine işaret etse bile retain cycle oluşmaz.
⚠️
weakreferanslar opsiyonel (?) olmalıdır. Çünkü ARC nesneyi yok ettiğinde referans otomatik olaraknilolur.
Retain Cycle Nedir?
Retain cycle, iki (veya daha fazla) nesnenin birbirini strong referansla tutarak, ARC’nin referans sayısını sıfıra düşürememesi durumudur. Bu durumda nesneler hafızada kalır ve deinit tetiklenmez; bu da bir memory leak’tir.
Basit bir örnek :
class A {
var b: B?
}
class B {
var a: A?
}
var objA: A? = A()
var objB: B? = B()
objA?.b = objB
objB?.a = objA
objA = nil
objB = nil
Bu kodda A ve B sınıfları karşılıklı olarak birbirine strong referans verdiği için:
objAsilinmez çünküobjB.ahâlâ onu tutar.objBsilinmez çünküobjA.bhâlâ onu tutar.
Sonuç: İki nesne de bellekten atılamaz → Memory leak.
Çözüm: Weak Referans Kullanmak
class B {
weak var a: A?
}
Bu sayede B sınıfı içindeki a değişkeni ARC tarafından referans sayacına dahil edilmez.
Biri silindiğinde diğerinin yaşam döngüsü tamamlanır → Retain cycle kırılır.
Closure Yoluyla Retain Cycle’a Sebep Olma
❌ Problemli Kod:
class MyViewModel {
var onDataFetched: (() -> Void)?
func fetchData() {
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
self.onDataFetched?()
}
}
}
Bu kodda self closure içinde strong olarak tutuluyor. Bu closure da self içinde bir property olduğundan retain cycle oluşuyor:
MyViewModel→ closure (strong)- closure →
MyViewModel(strong)
Bu döngü asla kırılmadığı için ARC nesneyi temizlemiyor.
✅ Çözüm: Weak Capture List
func fetchData() {
DispatchQueue.global().asyncAfter(deadline: .now() + 1) { [weak self] in
self?.onDataFetched?()
}
}
[weak self]ileselfartık ARC sayacını artırmaz.selfnil olmuşsa bile uygulama çökmez.
Bu refleksi kazanmak zaman alıyor ama kritik. Bir ViewModel’de
*[weak self]* koymayı unuttuğumda ekranda “ghost ViewController” kalıntılarıyla çok uğraştım.
Sonradan Edindiğim Alışkanlıklar
[weak self]’i closure’larda refleks olarak kullanıyorum.- Delegate’leri her zaman
weaktanımlıyorum. - Xcode Memory Graph’ı düzenli kullanıyorum.
Swift’te ARC, düşük seviyeli belleği bizden saklar. Ama bu onun sorunsuz olduğu anlamına gelmez.
ARC’yi anlamak, Swift’te başarılı olmanın yegane yoludur. Ben kendi retain cycle’larımla mücadele ederken, hem kod kalitemi hem de düşünme şeklimi değiştirdim. Umarım siz mücadele etmeden anlayabilirsiniz.
메타데이터
- post_id
- 0d45ecc010f4
- slug
- swiftte-arc-automatic-reference-counting-ile-bellek-yönetimi-0d45ecc010f4
- url
- https://medium.com/@umutkonmus/swiftte-arc-automatic-reference-counting-ile-bellek-y%C3%B6netimi-0d45ecc010f4
- canonical_url
- https://medium.com/@umutkonmus/swiftte-arc-automatic-reference-counting-ile-bellek-y%C3%B6netimi-0d45ecc010f4
- author_url
- https://medium.com/@umutkonmus
- status
- ok
- fetched_at
- 2026-07-16 05:33:41