/ / Po zwolnieniu obiektu należy do innego obiektu - zarządzanie pamięcią xcode - cel-c, kakao, xcode, zarządzanie pamięcią

Po zwolnieniu obiektu należy do innego obiektu - zarządzanie pamięcią xcode - cel-c, kakao, xcode, zarządzanie pamięcią

Jest [[MyObject itemProperty] release] do przyjęcia?

Obecnie mam MyObject pobiera niektóre dane iustawia go na itemProperty. Delegat MyObject następnie odpala i wykorzystuje dane itemProperty MyObject i wydaje je. Czy jest to akceptowalny sposób zarządzania pamięcią?

Powiedziano mi z różnych książek, że powinieneś zwolnić tylko zadeklarowany przedmiot. Jakieś wskazówki lub alternatywny sposób?

Odpowiedzi:

2 dla odpowiedzi № 1

Polecam wbrew podejściu, które opisujesz ... Twój instynkt zadawania pytań na ten temat jest słuszny, ponieważ prawdopodobnie doprowadzi to do kłopotów.

Obiekty są odpowiedzialne za zarządzanie własnymistan wewnętrzny, a posiadanie delegata ingeruje w ten stan wewnętrzny w ten sposób jest dość niezwykłe. Normalna praktyka oczyszczania pamięci jest konieczna MyObject zwolnij pamięć w jego dealloc metoda:

- (void)dealloc {
[item release];
[super dealloc];
}

W rzeczywistości, jeśli wdrażasz dealloc tak jak powinieneś posprzątać MyObject, po wysłaniu przez delegata komunikatu zwolnienia do obiektu na stronie itemProperty będzie oznaczać, że itemProperty obiekty zostają dwukrotnie wypuszczone, co spowoduje wyjścieitemProperty zachowuje się w nieoczekiwanym stanie i może spowodować jego dezalokację wcześniej .Jeśli kiedykolwiek zmienisz aplikację, aby inne obiekty korzystały z itemProperty, to zostaną one w tajemniczy sposób zwolnione po wywołaniu delegata.

Z drugiej strony, jeśli nie uporządkujesz pamięci dealloc, natrafiasz na sytuację, w której polegaszo wezwaniach delegata do zapewnienia właściwego zarządzania pamięcią. Czy naprawdę możesz zagwarantować, że metoda delegatów ZAWSZE zostanie wywołana w pewnym momencie Twojej aplikacji? Bezbłędnie? Nawet jeśli istnieją wyjątki lub inne warunki błędu, które mogą spowodować nietypowy przebieg wykonywania dla aplikacji?

Nawet jeśli możesz to zagwarantować, jako logikę aplikacjizmiany, to może już nie być przypadek, a zapomnisz, że delegat zajmuje się zarządzaniem pamięcią, prowadząc do wycieku lub segfault.Z pewnością, inni programiści kakao utrzymujący twój kod nie pomyśleliby spojrzeć na delegata do zarządzania pamięcią i prawdopodobnie będzie miał problemy z debugowaniem, które się pojawią.

W takim przypadku poproś delegata, aby właśnie skorzystał z itemProperty bez zatrzymywania, zwalniania lub autoreleasingu(chyba, że ​​delegat musi zagwarantować, że itemProperty nadal będzie po, być może, MyObject już nie ma). Gdy obiekt MyObject zostanie zwolniony, dane itemProperty zostaną wówczas zwolnione.


0 dla odpowiedzi nr 2

Zwykle wydajesz tylko wtedy, gdy przydzielisz, dodasz lub skopiujesz coś. Ponieważ nie dostarczyłeś żadnego innego kodu poza wypuszczeniem, ciężko powiedzieć, czy powinieneś / powinnaś zwolnić.

Z tego, co powiedziałeś, najlepsze wydaje się być rozwiązanieza pomocą puli autoreas. Po pobraniu danych wywołaj MyObject [itemProperty autorelease]. Następnie zostanie ono automatycznie zwolnione po tym, jak Twój delegat go użyje. Jednak zależy to od tego, jak to wszystko robisz :-)

Znowu pomoże ci więcej kodu.


0 dla odpowiedzi № 3

Po pierwsze nie zadeklaruj obiektu, Twoje obiekty tworzą inne obiekty, posiadają je, przekazują je itd.

Nigdy nie wypuszczaj czegoś, co nie posiadasz. Zwolnienie obiektu oznacza "Nie chcę już posiadać tego obiektu". Jeśli już go nie posiadasz, co zrezygnujesz? Oczekuj złamania, gdy zrobisz złe mojo w ten sposób.

Jeśli chcesz, aby obecny właściciel przestał być właścicielem, powiedz to. Zasadniczo będzie to coś w stylu [myObject setItemProperty:nil] (lub myObject.itemProperty = nil). Lub możesz dostarczyć nowy obiekt. Tak czy inaczej, obowiązkiem obecnego właściciela jest powstrzymanie jego posiadania.