Frage an objective-c, ios – Wird ein zugeordnetes Objekt automatisch freigegeben?

14

Hinweis: Diese andere Frage scheint relevant zu sein, ist aber nicht:Wann wird ein zugeordnetes Objekt freigegeben?

Ich füge eine zweite Beschreibung zu a hinzuUIView Beispiel wie folgt:

- (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);   
}

Wenn dasUIView Deallocs, wird die zugehörige Beschreibung 2 freigegeben? Gibt es eine Möglichkeit, dies automatisch zu erreichen?

Deine Antwort

4   die antwort
64

Wenn du eigentlich willstsehen Die Beschreibung der gesamten Dealloc-Zeitleiste finden Sie in WWDC 2011, Session 322, 36:22. Hier ist jedoch der grundlegende Überblick (ich wollte mich daran erinnern, daher ist dies ein tatsächlicher Kommentar in einem Teil meines Codes).

Beachten Sie, dass die zugehörigen Objekte am Ende des Lebenszyklus freigegeben werden.

// 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()
Wenn der Referenzzähler auf 0 geht, beginnt das Objekt zu sterben, und dieser Codepfad wird ausgeführt. Es gibt einige Einstellungen, um neue schwache Referenzen und andere Dinge zu verbieten, und dann beginnt die Dealloc-Kette. Wenn die Freigabe-Kette abgeschlossen ist, werden alle Instanzvariablen zerstört (unter ARC). Die zugehörigen Objekte sind nur eine Karte, die zusammen mit dem Rest des Materials angehängt wird (nun, es war früher eine std :: map <> - ich habe in letzter Zeit nicht gesucht, aber ich wollte wirklich, dass sie ein Array für kleine verwenden Anzahl zugehöriger Objekte, später eine Karte verwenden - um den Speicherverbrauch zu begrenzen). Jody Hagins
+1 Das ist großartiges Zeug, Jody. Möglicherweise muss ich die Sitzung tatsächlich ansehen, da ich nicht verstehen kannwoher Dieser Code würde gefunden werden. Aber das ist mehr mein Unverständnis darüber, wie Obj-C zusammengesetzt ist, als alles andere. Dan Rosenstark
Dies ist eine großartige Information, Jody, danke. Um nur hinzuzufügen, dass ich herausgefunden habe, dass in iOS4, wenn Sie einem Objekt, das auch als Beobachter registriert ist, zugeordnete Objekte hinzufügen, die zugeordneten Objekte niemals freigegeben werden, obwohl das Objekt freigegeben wird. Die Verwendung von KVO in Kombination mit zugehörigen Objekten in iOS4 unterbricht diese Kette also irgendwie. David
3

Ja. Wenn die Zuordnung eines Objekts aufgehoben wird, werden alle zugeordneten Objekte (die das Symbol verwenden) gelöschtRETAIN oderCOPY Assoziationsarten) werden automatisch freigegeben.

0

Abschnitt 4 in Jody Hagins 'Antworten sagt "Verknüpfte Referenzen löschen", was nicht explizit bedeutet, dass die Referenzen freigegeben werden. Daher habe ich den folgenden Code (Hinweis WITHOUT ARC) verwendet, um dies zu testen.

@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];
}

Das Aufrufen des obigen Codes führt in der Tat dazu, dass - [AssociatedObjectHelper dealloc] mit dem folgenden Stack-Trace aufgerufen wird:

#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]

Getestet auf Xcode 7.0.1

3

Kurz gesagt, ja - wenn das besitzende Objekt freigegeben wird, werden beibehaltene zugeordnete Objekte freigegeben. Siehe den ersten Abschnitt von AppleDokumentation

Ich habe diesen Abschnitt gesehen. Wo steht, dass es veröffentlicht wurde? Dan Rosenstark
Danke @borrrden das hilft. Dan Rosenstark
@Yar ganz deutlich im vorletzten Satz des ersten Abschnitts (Assoziationen erstellen): "Wenn die Zuordnung des Arrays jedoch aufgehoben wird (Punkt 2), wird die Übersicht freigegeben und in diesem Fall auch die Zuordnung aufgehoben." :) borrrden

Verwandte Fragen