iOS Bellek Yönetimi: ARC ve Retain Cycles Sorunu

# iOS Bellek Yönetimi: ARC ve Retain Cycles Sorunu

iOS'ta belleği otomatik olarak yöneten sisteme ARC (Automatic Reference Counting) denir. Her nesne kaç yerde kullanılıyor, kaç referans var diye sayar. Referans sayısı sıfıra düşünce nesneyi bellekten siler.

Bu sistemi anlamak için basit bir benzetme: Bir kitabı kaç kişi eline alırsa o kadar referans var. Son kişi bırakınca kitap kütüphaneden çıkarılır.

Ancak bir sorun var: İki nesne birbirini tutarsa ne olur? A nesnesi B'yi tutuyor, B de A'yı tutuyor. İkisinin referans sayısı asla sıfıra düşmez. İkisi de bellekte sıkışıp kalır. Buna retain cycle (döngüsel referans) denir.

Hatalı kod:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1class Person {
2var name: String
3var apartment: Apartment?
4init(name: String) { self.name = name }
5}
6
7class Apartment {
8var number: Int
9var tenant: Person?
10init(number: Int) { self.number = number }
11}
12
13var john: Person? = Person(name: "John")
14var apt: Apartment? = Apartment(number: 101)
15
16john?.apartment = apt
17apt?.tenant = john
18
19john = nil
20apt = nil
21// Sorun: İkisi de bellekte kalıyor! Silinmiyor.

Çıktı: John ve Apartment nesneleri bellekten çıkmaz, bellek sızıntısı oluşur.

Döngüyü kırmak için bir taraftaki referansı zayıflaştırırız:

1class Apartment {
2var number: Int
3weak var tenant: Person? // Zayıf referans!
4init(number: Int) { self.number = number }
5}
6
7var john: Person? = Person(name: "John")
8var apt: Apartment? = Apartment(number: 101)
9
10john?.apartment = apt
11apt?.tenant = john
12
13john = nil
14apt = nil
15// Şimdi ikisi de silinir. Bellek serbest kalır.
16[/cod]
17
18**Çıktı:** Her iki nesne de başarıyla bellekten çıkar.
19
20- **`weak`:** Referans `nil` olabilirse (opsiyonel). Çoğu durumda bunu kullan.
21- **`unowned`:** Referans asla `nil` olmayacaksa. Ama hatalı kullanırsan crash olur.
22
23Eğer emin değilsen `weak` kullan.
24
25Kapaış (closure) içinde `self` kullanırsan retain cycle oluşabilir:
26
27[kod]
28let closure = { [weak self] in
29print(self?.name)
30}

`[weak self]` capture list'i döngüyü kırar.

ARC harika ama retain cycle'lar tuzak. İki nesne birbirini tutarsa, birini `weak` yap. Closure'larda `[weak self]` kullan. Böyle bellek sızdırmazsın.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz