6 Stimmen

Autorelease-Zielfernrohr

Ich habe mich gefragt, wie die Autorelese auf dem iPhone funktioniert. Ich dachte, sobald man eine Autorelease an ein Objekt sendet es ist garantiert die bis zum Ende des Geltungsbereichs des Blocks beibehalten werden soll, die autorelease gesendet wurde. Ist das richtig?

Ich initialisierte eine Ansicht aus einer NIB in der applicationDidFinishLaunching wie unten:

    (void)applicationDidFinishLaunching:(UIApplication *)application {

    loginViewController = [[[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil] autorelease];

    [window addSubview: [loginViewController view]];
    [window makeKeyAndVisible];
}

und die Ansicht war überhaupt nicht zu sehen, auf dem Bildschirm war nur die UIWindow

Nachdem ich die autorelease Ab dem Ende der Controller-Initialisierung lief alles reibungslos ab.

Worum geht es hier?

Zum Wohl, K.

13voto

Don McCaughey Punkte 8962

Wenn Sie anrufen autorelease geben Sie das Eigentum an dem Objekt an den aktuellen Autorelease-Pool ab. Die Ausführungsschleife erstellt einen neuen Autorelease-Pool, bevor sie ein Ereignis auslöst (z. B. applicationDidFinishLaunching: ) und vernichtet diesen Pool, wenn das Ereignis beendet ist.

Wenn Sie das Eigentum an Ihrem LoginViewController in den Pool für die automatische Freigabe, wird sie gleich nach der Freigabe der applicationDidFinishLaunching: zurück. Wenn der View-Controller sich selbst deallociert, entfernt er seine Ansicht aus der Superansicht (in diesem Fall Ihr Fenster).

Ihr Anwendungsdelegierter sollte das Eigentum an der LoginViewController y release es in der App-Delegate's dealloc Methode (oder wenn Sie mit der Anmeldung fertig sind und zu einer anderen Ansicht übergegangen sind).

4voto

Rob Napier Punkte 265102

Um Dons Antwort zu ergänzen: Die Aussage "Sie geben das Eigentum an dem Objekt an den aktuellen Autorelease-Pool ab" kann etwas verwirrend sein. Dies könnte so missverstanden werden, dass das Objekt garantiert zerstört wird, wenn der Autorelease-Pool geleert ist. Dies ist nicht korrekt (obwohl es in diesem Fall passieren wird). Senden von -autorelease verlangt, dass der Autorelease-Pool eine -release Nachricht, wenn es entleert ist. Wenn das -release Nachricht retainCount = 0, so wird das Objekt zerstört.

Um also das zu tun, was Don empfiehlt, müssen Sie eine Ivar erstellen, um diesen View Controller zu verfolgen. Seine Erklärung, warum die Ansicht verschwindet, ist genau richtig; aber Sie wollen nicht einfach den View Controller auslaufen lassen. Sie wollen ihn festhalten und ihn freigeben, wenn Sie damit fertig sind.

@interface ... {
   LoginViewController *_loginViewController;
}

@property (readwrite, retain) LoginViewController *loginViewController;

@implementation ...
@synthesize loginViewController = _loginViewController;

- (void)applicationDidFinishLaunching:(UIApplication *)application {

    self.loginViewController = [[[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil] autorelease];

    [window addSubview: [loginViewController view]];
    [window makeKeyAndVisible];
}

- (void)dealloc {
    [_loginViewController release]; _loginViewController = nil;
    [super dealloc];
}

0voto

Georg Schölly Punkte 120083

Der Autoreleasepool wird am Ende der Laufzeitschleife bereinigt. Das heißt, solange Sie Methoden aufrufen und Dinge tun, ist er noch da.

Ich sehe den Fehler in Ihrem Code nicht, aber das Fenster wird in Ihrem Beispiel korrekt beibehalten.

0voto

Ashley Clark Punkte 8783

Da Sie Ihre LoginViewController an den Autorelease-Pool wird er am Ende der Laufschleife freigegeben. Wenn dies geschieht, wird auch die Ansicht freigegeben und nicht mehr angezeigt.

0 Stimmen

Die Aussicht sollte durch das Fenster erhalten bleiben. (Ich habe allerdings keinen Zugriff auf die Dokumentation.)

1 Stimmen

Wenn jedoch der View-Controller deallocated wird, entfernt er die von ihm verwaltete View aus seiner Superview.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X