2012-05-22 11 views
6

Bis zu fünf Minuten war ich mir sicher, dass mein Verständnis von Objective-Referenzzählung ausgezeichnet ist, aber als ich anfing Objekte zu überprüfen, war ich sehr überrascht zu sehen, was ich sah.Objective c - Referenzzählung

Zum Beispiel MyViewController hat eine UITableView:

.h-Datei

@interface RegularChatViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> 
{ 
    UITableView *_tableView; 
} 
@property (nonatomic, retain) IBOutlet UITableView *tableView; 

.m-Datei

@synthesize tableView = _tableView; 

- (void)loadView 
{ 
    _tableView = [[UITableView alloc] init]; // STEP ONE 
    NSLog(@"tableView retain count: %d",[_tableView retainCount]); 

    self.tableView.frame = CGRectMake(0, 0, 320, tableHeight); // STEP TWO 
    NSLog(@"tableView retain count: %d",[_tableView retainCount]); 

    [self.view addSubview:self.tableView]; // STEP THREE 
    NSLog(@"tableView retain count: %d",[_tableView retainCount]); 
} 

der Eingang Zu meiner Überraschung war:

tableView retain count: 1 
tableView retain count: 2 
tableView retain count: 3 

offensichtlich SCHRITT EINS Erhöhung Beibehaltungszähler um 1 mit alloc

Ich weiß auch, dass SCHRITT DREI Anstieg Beibehaltungszähler um 1 mit addSubview

Aber was ist in SCHRITT ZWEI los ??? Warum hat es die Retain-Anzahl erhöht?
gibt es etwas mit ARC zu tun ??

+0

Vielleicht, weil '.frame' nicht ohne die Tabellenansicht existieren kann und daher die Retain-Anzahl addiert? –

+0

Gute Schätzung; aber 'frame' gibt eine Struktur direkt zurück; nicht einmal eine Referenz. Keine Abhängigkeit dort. – bbum

Antwort

7

Laut Apple docs auf NSObject Protocol Reference für die retainCount Methode:

Wichtige Diese Methode ist in der Regel keinen Wert in Managementfragen Speicher debuggen. Da eine beliebige Anzahl von Framework-Objekten möglicherweise ein Objekt beibehalten hat, um Verweise darauf zu halten, und gleichzeitig Autorelease-Pools eine beliebige Anzahl von verzögerten Releases für ein Objekt enthalten, ist es sehr unwahrscheinlich, dass Sie daraus nützliche Informationen erhalten Methode.

+1

In der Tat. Ich mache mir große Sorgen, wenn Entwickler sehen, wie sie die Anzahl der Retains in ihrem Code abmelden. Solange Sie den Eigentumsregeln folgen und ab und zu das Leaks-Tool verwenden, sind Sie golden. –

+0

das ist eine Erleichterung :) danke – Eyal

2

Sobald Sie mit jeden Rahmen Methode oder Funktion auch immer, die retainCount Methode völlig unbrauchbar wird, interagieren, weil Sie nicht wissen, was diese Dinge in ihren schwarzen Boxen zu tun (sie Ihre Objekte hinzufügen könnten Pools Autorelease oder was auch immer) und Sie sollten sich nicht darum kümmern.

Verwenden retainCount zum Debuggen von Speicherverwaltungsproblemen ist immer eine schlechte Idee. Siehe this answer für noch mehr Gründe, um es zu vermeiden.

2

Ich habe eine praktische Anleitung hier: When to use retainCount?

Kurz gesagt, retainCount selten bedeutet, was Sie denken, es wird. Ohne zu wissen, wie UITableView und UIView implementiert sind, können Sie nicht wissen, was die Retain-Anzahl sein sollte. Und wir nehmen nicht einmal Autorelease in Betracht ...

+0

Das ist wirklich keine hilfreiche Webseite, und ich hasse es, hier gepostet zu sehen. Ein einziges Wort ohne Erklärung gibt nur dem Link-Poster ein Lächeln; Es hilft dem Fragesteller nicht ein bisschen. –

+0

Haben Sie nach unten geblättert? Beachten Sie auch, dass ich alle relevanten Informationen in die Antwort aufgenommen habe. –

+0

Die Antwort ist natürlich in Ordnung. Ich war noch nie auf der Seite gescrollt, nein. Mit den Links unten ist es viel besser als ich gedacht habe, aber ich kann nicht der Einzige sein, der die Vermutung annahm, dass da nichts anderes da ist, da du es anscheinend so eingerichtet hast, dass es für die meisten Bildschirme keine gibt der untere Inhalt zeigt sich zunächst. –

0

Nun in Schritt zwei: - durch Verwendung von Selbst. tableView, getter der tableview -Eigenschaft (die gesetzt ist behalten) wird aufgerufen. So wie Ihre Eigenschaft zugeordnet ist und behalten beide so behalten Zählung erhöht sich jeweils.

Immer wenn Sie eine beibehaltene Eigenschaft zuweisen müssen, sollten Sie ihre Getter-Methode überschreiben, und dies wird als faule Instanziierung bezeichnet.

Besser zuteilen Sie Ihre Tabellenansicht in seinem getter z.

-(UITableView *) tableView 
{ 
    if(!_tableView) { 
      _tableView = [[UITableView alloc]init]; 
    } 

    return _tableView; 
} 
0

self.tableView.frame wird retain und autorelease wenn die tableView vom Getter zurückkehrt.