Swift'de Referans Döngüsü
Bir geliştirici için bellek yönetimi genellikle önemsiz değildir. Otomatik Referans Sayımı (ARC) sayesinde , iOS geliştiricileri için bellek yönetimi kolaylaştırılmıştır. Sadece çoğu zaman çalışır. Ancak, referans döngüsü çok aldatıcıdır ve birçok deneyimli geliştiricinin bu tür hatalar yaptığını gördüm.
Resmi belgeler esas olarak iki A<->B nesnesi arasındaki temel referans döngüsünden bahseder. Bu makalede göstereceğim şey, tespit edilmesi daha zor olan 3 veya 4 nesne arasındaki referans döngüsüdür.
Bellek Sızıntısı Olan Uygulama
Demo, iki ekranlı çok basit bir iOS projesidir. "InitialViewController" ilk ekranında, kullanıcı ikinci ekran "SampleViewController"ı başlatmak için düğmeye tıklayabilir, ardından kullanıcı ikinci ekranı kapatmak için kapat düğmesini tıklayabilir. İkinci ekran VIP temiz mimarisi kullanılarak kodlanmıştır.
Kullanıcı, Uygulamayı kullanmaktan keyif alırken, arkasından bellek sızdırıyor. Xcode'un “Debug Memory Graph” özelliğinden aşağıdaki ekrandan, “SampleViewController”, “SamplePresenter”, “SampleInteractor” ve “SampleRouter” her birinin 5 örneğinin sızdırıldığını görebiliriz. Çok fazla bellek sızıntısı olduğunda, Uygulama sistem tarafından öldürülecek ve bu, Uygulama geliştiricisi için çok utanç verici olacaktır.
Birkaç Nesne İçinde Referans Döngüsü
Hafızanın neden sızdırdığını öğrenmek için aşağıdaki kaynak koduna yakından bakalım.
class SampleViewController: UIViewController, SampleViewControllerInterface {
var interactor: SampleInteractorInterface?
// omitted the rest for simplicity
}
class SampleInteractor: SampleInteractorInterface {
var presenter: SamplePresenterInterface?
// omitted the rest for simplicity
}
class SamplePresenter: SamplePresenterInterface {
var viewController: SampleViewControllerInterface?
var router: SampleRouterInterface?
// omitted the rest for simplicity
}
class SampleRouter: SampleRouterInterface {
var viewController: UIViewController?
// omitted the rest for simplicity
}
Aslında içinde iki referans döngüsü vardır:
- Interactor->Presenter->ViewController->Interactor
- Interactor->Presenter->Router ->ViewController->Interactor
Bunu çözmek için, aşağıdaki değişiklik gibi zayıf referansları kullanabiliriz.
O halde, aşağıdaki şemaya göre artık VIP için bir referans döngümüz yok.
Blok Yakalama ile İlgili Referans Döngüsü
Hoo! Bu harika hissettiriyor çünkü az önce iki referans döngüsü belirledik ama işimiz henüz bitmedi. Uygulamayı şimdi çalıştırırsanız, hala bellek sızıntılarımız olduğunu göreceksiniz. Nedeni, kodun aşağıdaki kısmıdır.
class CustomButton: UIView {
var buttonClickHander: (() -> Void)?
// omitted the rest for simplicity
}
class SampleViewController: UIViewController, SampleViewControllerInterface {
private lazy var customButton: CustomButton = {
let button = CustomButton()
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
private func setUpUI() {
view.addSubview(customButton)
customButton.buttonClickHander = {
self.interactor?.customButtonClicked()
}
// ...
}
}
Sorunun nerede olduğunu öğrendikten sonra düzeltmek kolaydır, aşağıya bakın.
Özet
Özetlemek gerekirse, birkaç nesnede meydana gelen iki tür referans döngüsünü ele aldık. Demo projesini burada bulabilirsiniz ve sabitleme, kolay incelemeniz için bir Çekme İsteğinde hazırlanmıştır . Umarım bu makale, referans döngüsünü daha iyi anlamanıza ve bundan kaçınmak için kendinize güvenmenize yardımcı olur.

![Bağlantılı Liste Nedir? [Bölüm 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































