Pytanie w sprawie ios, objective-c – Czy skojarzony obiekt zostanie zwolniony automatycznie?

14

Uwaga: to inne pytanie wydaje się istotne, ale nie jest:Kiedy powiązany obiekt zostanie zwolniony?

Dodaję drugi opis doUIView przykład w następujący sposób:

- (void) setSecondDescription:(UIView*)view description2:(NSString*)description2 {
    objc_setAssociatedObject (view,&key,description2,OBJC_ASSOCIATION_RETAIN);
}

- (NSString*) secondDescription:(UIView*)view {
    return (id)objc_getAssociatedObject(view, &key);   
}

JeśliUIView deallocs, czy powiązany opis 2 zostanie zwolniony? Czy jest jakiś sposób, aby to się stało automatycznie?

Twoja odpowiedź

4   odpowiedź
3

Krótko mówiąc, tak - kiedy obiekt będący właścicielem zostanie zwolniony, zachowane powiązane obiekty zostaną zwolnione. Zobacz pierwszą sekcję Apple'adokumentacja

Dzięki @ borrrden, który pomaga. Dan Rosenstark
@Yar dość wyraźnie w drugim do ostatniego zdania pierwszej sekcji (Tworzenie powiązań): „Gdy tablica zostanie zwolniona, jednak (w punkcie 2), przegląd zostanie opublikowany i w tym przypadku również zwolniony.” :) borrrden
Widziałem tę sekcję. Gdzie to mówi, że jest wydane? Dan Rosenstark
0

Sekcja 4 w Jody Hagins 'odpowiedź mówi „Usuń powiązane odnośniki”, co wyraźnie nie oznacza, że ​​odniesienia są zwolnione. Użyłem następującego fragmentu kodu (uwaga BEZ ARC), aby to przetestować.

@interface AssociatedObjectHelper : NSObject
@end

@implementation AssociatedObjectHelper
- (void) dealloc
{
    NSLog(@"In %s", __FUNCTION__);
    [super dealloc];
}
@end

@implementation AppDelegate
...
- (void) testReleaseAssociatedObject
{
    static const NSString *key = @"testKey123";
    NSObject *ob = [NSObject new];
    AssociatedObjectHelper *assocOb = [AssociatedObjectHelper new];
    objc_setAssociatedObject(ob, key, assocOb, OBJC_ASSOCIATION_RETAIN);
    [assocOb release];
    [ob release];
}

Wywołanie powyższego kodu rzeczywiście kończy się wywołaniem - [AssociatedObjectHelper dealloc], z następującym śledzeniem stosu:

#0  0x000000010000528f in -[AssociatedObjectHelper dealloc]
#1  0x00007fff8a0bb89c in objc_object::sidetable_release(bool) ()
#2  0x00007fff8a0a537f in _object_remove_assocations ()
#3  0x00007fff8a0a1644 in objc_destructInstance ()
#4  0x00007fff8a0a1595 in object_dispose ()
#5  0x00007fff8a0bb89c in objc_object::sidetable_release(bool) ()
#6  0x000000010000e9b6 in -[AppDelegate testReleaseAssociatedObject]

Testowane na Xcode 7.0.1

64

Jeśli chcesz w rzeczywistościwidzieć opis całej osi czasu dealloc, patrz WWDC 2011, Sesja 322, 36:22. Jednak oto podstawowe podsumowanie (chciałem to zapamiętać, więc jest to rzeczywisty komentarz w kawałku mojego kodu).

Zauważ, że powiązane obiekty są uwalniane pod koniec cyklu życia.

// General Information
// We take advantage of the documented Deallocation Timeline (WWDC 2011, Session 322, 36:22).
// 1. -release to zero
//     * Object is now deallocating and will die.
//     * New __weak references are not allowed, and will get nil.
//     * [self dealloc] is called
// 2. Subclass -dealloc
//     * bottom-most subclass -dealloc is called
//     * Non-ARC code manually releases iVars
//     * Walk the super-class chain calling -dealloc
// 3. NSObject -dealloc
//     * Simply calls the ObjC runtime object_dispose()
// 4. object_dispose()
//     * Call destructors for C++ iVars
//     * Call -release for ARC iVars
//     * Erase associated references
//     * Erase __weak references
//     * Call free()
+1 To świetne rzeczy, Jody. Być może będę musiał rzeczywiście obejrzeć sesję, ponieważ nie mogę zrozumiećgdzie ten kod byłby zlokalizowany. Ale to raczej mój brak zrozumienia tego, jak Obj-C jest zestawiony niż cokolwiek innego. Dan Rosenstark
To świetna informacja, dzięki Jody. Jak dodać, dowiedziałem się, że w iOS4, jeśli dodasz powiązane obiekty do obiektu, który jest również zarejestrowany jako obserwator, powiązane obiekty nigdy nie zostaną zwolnione, nawet jeśli obiekt zostanie zwolniony. Tak więc użycie KVO w połączeniu z powiązanymi obiektami w iOS4 w jakiś sposób łamie ten łańcuch. David
Gdy licznik odniesie wartość 0, obiekt zaczyna umierać i ta ścieżka kodu jest wykonywana. Istnieje pewna konfiguracja, która uniemożliwia nowe słabe referencje i inne rzeczy, a następnie rozpoczyna się łańcuch dealloc. Kiedy łańcuch dealloc zostanie wykonany, wtedy wszystkie zmienne instancji zostaną zniszczone (w ARC). Powiązane obiekty są tylko mapą, która jest dołączona wraz z resztą rzeczy (cóż, kiedyś była to std :: map <> - ostatnio nie wyglądałem, ale naprawdę chciałem, żeby użyli tablicy dla małych liczby powiązanych obiektów, a następnie użyj mapy później - aby ograniczyć zużycie pamięci). Jody Hagins
3

Tak. Gdy obiekt jest zwolniony, wszelkie powiązane obiekty (które używająRETAIN lubCOPY typy skojarzeń) są automatycznie zwalniane.

Powiązane pytania