2012-01-31 5 views
6

Istnieje wiele pytań związanych z tym tematem, ale żaden z nich nie odpowiada na moje pytanie.Kluczowa wartość Zaobserwuj removeObserver, gdy obserwowany obiekt został zwolniony.

Chcę removeObserver z obiektu, gdy obiekt zostanie zwolniony. Używam KVO, ponieważ trzeba obserwować wiele pozycji, a NSNotification ma w tym przypadku ogromne obciążenie.

Oto scenariusz:

(wielokrotny) Obiekty są obserwowane przez różne inne przedmioty. Po zwolnieniu observer mogę usunąć go jako obserwatora. Ale kiedy zwolni się observed, muszę powiedzieć wszystkim observers, by usunęli się jako obserwatorzy. Jak to zrobić?

Odpowiedz

1

można oddzielnie opublikować powiadomienie od -(void)dealloc, gdy zaobserwowane uzyskać zwolniony. po otrzymaniu wszystkich pozostałych obserwatorów usunie wymagane powiadomienie.

+0

Nie będzie tyle powiadomień, a cały cel użycia kvo zostanie pokonany. Ponadto kończyłoby się to tak: 1. Obserwować jakąś właściwość obiektu. 2. Ze wszystkich obserwowanych obiektów zwolnij powiadomienie po zwolnieniu. 3. Wysłuchaj powiadomienia o anulowaniu i usuń obserwatora. To dużo pracy. Czy nie ma jakiegoś czystego rozwiązania? – Sailesh

3

Żagiel, jeśli obiekt (obserwowany) zostanie zwolniony, to nie można go zmienić lub jego wartość nie może zostać zmieniona, więc jeśli obserwatorzy obserwują obiekt zwolniony, a obiekt zwalniany nigdy nie będzie wysyłał żadnego rodzaju obserwacji powiadomienie to Czy jest jakaś zabawa z usuwaniem obserwatorów ???
~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ • hej, mam coś z here. Chodzi o to, że obserwujesz dodatkową właściwość, powiedzmy: alive i pisz w dealloc o obserwowanym jako alive = NO;, a ponieważ ta właściwość zostanie zmieniona, wszyscy obserwatorzy otrzymają powiadomienie, dzięki czemu możesz usunąć wszystkich obserwatorów.


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+2

Po wyświetleniu tego komunikatu o błędzie w konsoli, chcesz usunąćObserver, nawet jeśli nie jest to zabawne :). 'Instancja 0xd89f200 klasy MyClass została zwolniona, podczas gdy obserwatorzy wartości klucza nadal byli z nią rejestrowani. Informacje o obserwacjach wyciekły, a nawet mogą zostać pomyłkowo połączone z jakimś innym obiektem. " – Sailesh

+0

hmmm to poważna sprawa ... pozwól mi wyszukać, czy mogę znaleźć coś .. dzięki za odpowiedź :) –

+0

Edytowałem odpowiedź ... –

2

Myślę, że tutaj jest problem z projektowaniem. Obserwowany przedmiot nie powinien mieć na uwadze obserwatorów. Mówisz, że chcesz usunąć obserwatorów z metody obserwowanych obiektów dealloc. Ale dlaczego zostaje zwolniona? Jeśli nadal jest obserwowany, istnieje gdzieś własność, więc obiekt nie zostanie zwolniony. Dobry projekt powoduje, że żaden obserwator nie zostanie wybrany do czasu wywołania dealloc.

Wyobraź sobie widok, który rejestruje się jako obserwator w obiekcie modelu. Ten obiekt modelu jest zachowany w widoku lub w kontrolerze. Obiekt modelu nie wywoła dealloc, dopóki jest gdzieś zatrzymany. Dopiero po zwolnieniu ostatniego właściciela powinien wywołać dealloc. Powiedzmy, że wszystkie własności zostały zwolnione, z wyjątkiem kontrolera view/viewcontroller i pozostał jeden obserwator (widok). Teraz zanim view/viewcontroller zwalnia własność nad obiektem modelu, powinien także usunąć widok jako obserwator. Tak więc do czasu wywołania metody dealloc nie powinno być żadnego obserwatora.

+0

Rozważ przypadek, gdy dwa obiekty obserwują się nawzajem. Proponowany wzór tworzy cykl zatrzymania. W każdym przypadku obserwator może mieć jedynie słabe odniesienie do obserwowanego, a wykonywanie innych czynności może nie być dobrym projektem, biorąc pod uwagę wszystkie inne aspekty aplikacji. – Sailesh

+1

Moim zdaniem, dwa obiekty obserwujące siebie nawzajem to przypadek złego projektu. –

+0

Dzięki za tę odpowiedź. Zdałem sobie sprawę, że moja decyzja o słabym posiadaniu tego modelu była błędna. Zmieniłem się teraz w silny związek i mam nadzieję, że teraz nie widzę wielu awarii KVO. – rounak