Olay dinleyicileri zayıf referanslarda tutulmalı mı?


9

Genellikle olay dinleyicileri onları kaydeden nesneden daha uzun olmamalıdır.

Olay dinleyicilerinin varsayılan olarak zayıf referanslarla tutulması gerektiği anlamına gelir (nesne dinleyicileri tarafından zayıf koleksiyonlarda saklanır)?

Dinleyicinin yaratıcısını geçmesi gereken geçerli durumlar var mı?

Ya da belki böyle bir durum bir hatadır ve buna izin verilmemelidir?


Zayıf referanslar genellikle örnekler ile temsil edilir ve bu örnekler de çöp olarak toplanmaları gereken noktaya kadar birikebilir. Yani ücretsiz bir öğle yemeği değil. Zayıf referansları temizleyen aynı mantık güçlü referansları temizleyebilir.
Frank Hileman

Yanıtlar:


7

Olay dinleyicileri neden onları kaydeden nesneden daha fazla yaşamamalı? Olay dinleyicilerinin kontrol yöntemleriyle (GUI örneğini alırsak) - veya daha doğrusu, GUI araç setinin kontrollerini devralan sınıf nesnelerine göre yöntemlerle kaydedilmesi gerektiğini varsayıyorsunuz. Bu bir zorunluluk değildir - örneğin, olay dinleyicilerini kaydetmek için özel bir nesne kullanabilir ve daha sonra bu nesneyi atabilirsiniz.

Ayrıca, olay dinleyicileri zayıf bir şekilde yönlendirildiyse, bu referansı hiç kullanmasanız bile bunlara referanslar tutmanız gerekir. Bunu yapmazsanız dinleyici rastgele bir zamanda toplanır. Yani, bir hata alırız

  • Yanlışlıkla oluşturmak kolaydır (tek yapmanız gereken bir nesneyi asla kullanmayacağınız bir referans değişkeninde saklamaktır).
  • Dikkat edilmesi zor (bu hata yalnızca GC bu nesneyi toplarsa alırsınız).
  • Hata ayıklaması zor (hata ayıklama oturumunda - her zaman bir yayın oturumu gibi çalışır - bu hata yalnızca GC nesneyi topladığında karşılaşırsınız).

Ve bu hatadan kaçınmak yeterince teşvik edici değilse, işte biraz daha:

  1. Oluşturduğunuz her dinleyici için bir ad düşünmeniz gerekir .

  2. Bazı diller, hiç yazılmamış veya hiç okunmayan özel bir üye alanınız varsa uyarı oluşturacak statik analiz kullanır. Bunu geçersiz kılmak için bir mekanizma kullanmanız gerekecek.

  3. Olay dinleyicisi bir şey yapar ve güçlü referansı olan nesne toplandıktan sonra bir şey yapmayı durduracaktır. Artık programın durumunu etkileyen ve GC'ye bağlı bir şey var - bu da GC'nin programın somut durumunu etkilediği anlamına gelir. Ve bu KÖTÜ !

  4. Başka bir dolaylı düzeyiniz olduğundan ve referansın toplanıp toplanmadığını kontrol etmeniz gerektiğinden zayıf referansları işlemek daha yavaştır. Olay dinleyicilerinin zayıf referanslarda bulunması gerekiyorsa bu bir sorun olmazdı - ama değil!


5

Genel olarak, evet, zayıf referanslar kullanılmalıdır. Ama önce “olay dinleyicileri” ile ne demek istediğiniz konusunda net olmalıyız.

Callbacks

Bazı programlama stillerinde, özellikle de eşzamansız işlemler bağlamında, hesaplamanın bir kısmını belirli bir olayda yürütülen geri arama olarak göstermek yaygındır. Örneğin, Promise[ 1 ] then, önceki adımın tamamlanmasının ardından bir geri arama kaydeden bir yönteme sahip olabilir :

promise =
    Promise.new(async_task)                # - kick off a task
    .then(value => operation_on(value))    # - queue other operations
    .then(value => other_operation(value)) #   that get executed on completion
... # do other stuff in the meanwhile
# later:
result = promise.value # block for the result

Burada, thensöz verilen (olay kaynağı) geri aramaya bir referansı tutan tek nesne olduğundan, tarafından kaydedilen geri aramaların güçlü referanslarla tutulması gerekir. Bu, vaadin kendisinin sınırlı bir ömre sahip olması ve vaat zinciri tamamlandıktan sonra toplanacak çöp olması nedeniyle bir sorun değildir.

Gözlemci Düzeni

Gözlemci modelinde, bir öznenin bağımlı gözlemcilerin bir listesi vardır. Konu bir duruma girdiğinde, gözlemciler bazı arayüzlere göre bilgilendirilir. Gözlemciler konuya eklenebilir ve konudan çıkarılabilir. Bu gözlemciler anlamsal bir boşlukta mevcut değiller, ancak bir amaçla olayları bekliyorlar.

Bu amaç artık mevcut değilse, gözlemciler özneden çıkarılmalıdır. Çöp toplanan dillerde bile, bu kaldırma işleminin manuel olarak yapılması gerekebilir. Bir gözlemciyi kaldıramazsak, özneden gözlemciye yapılan referans ve onunla birlikte gözlemcinin başvurduğu tüm nesneler canlı tutulacaktır. (Şimdi işe yaramaz) gözlemci hala bilgilendirileceğinden bu, belleği boşa harcar ve performansı düşürür.

Zayıf referanslar, gözlemcinin çöp toplanmasına izin verdiği için bu bellek sızıntısını düzeltir. Konu tüm gözlemcileri bilgilendirmek için etrafa gittiğinde ve bir gözlemciye zayıf referanslardan birinin boş olduğunu tespit ettiğinde, bu referans güvenle kaldırılabilir. Alternatif olarak zayıf referanslar, öznenin toplama üzerine gözlemciyi kaldıracak bir temizleme geri çağrısı kaydetmesine olanak verecek şekilde uygulanabilir.

Ancak zayıf referansların yalnızca bir gözlemciyi kaldırmayı unutarak hasarı sınırlayan bir bant yardımı olduğunu unutmayın. Doğru çözüm, artık gerekli olmadığında bir gözlemcinin kaldırılmasını sağlamak olacaktır. Seçenekler şunları içerir:

  • Elle yapmak, ancak bu hatalara yatkındır.

  • Java veya usingC # kaynak ile denemek için benzer bir şey kullanma .

  • RAII deyimi gibi deterministik yıkım. Deterministik çöp toplama olan bir dilde, bunun yıkıcıyı tetiklemek için özneden gözlemciye zayıf referanslar gerektirebileceğini unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.