Domanda

Da qualche parte lo stavo leggendo - per quanto riguarda gli avvisi di memoria insufficiente e rinunciare a una vista non visibile con tutte le sue visualizzazioni secondarie (= un pennino intero, penso), dovresti farlo:

-(void)dealloc {
    [anView release], anView = nil;
    [someImageView release], someImageView = nil;

    [super dealloc];
}

anziché

-(void)dealloc {
    [anView release];
    [someImageView release];

    [super dealloc];
}

Qual è la ragione per mettere a terra quei puntatori a zero (= "nessun oggetto"), dopo aver chiamato il rilascio? Fammi indovinare: qualche altro metodo avrebbe potuto-trattenere la vista per qualche motivo (qualcuno ha qualche esempio per quando ciò potrebbe accadere?), Quindi succede la cosa didReceiveMemoryWarning e rilasci un'intera pennino + vista che attualmente non è visibile (cioè in un'app multiview). Non appena l'utente vuole vedere di nuovo quella vista, caricheresti rapidamente di nuovo il pennino e poi: carica tutte le viste, collega le prese e BANG! Le altre tue viste trattenute ora sono sospese senza alcun puntatore da qualche parte solitario nel mattone della memoria, causando una perdita di memoria profonda e profonda fino a quando l'app non si arresta in modo anomalo.

giusto / sbagliato?

È stato utile?

Soluzione

anziché eseguire il rilascio esplicito e impostato su zero, se i tuoi accessor hanno proprietà associate a te yoc e fai come segue un metodo più conciso:

- (void) dealloc
{
    self.retainedProperty1 = nil;
    self.retainedProperty2 = nil;
    self.copiedProperty = nil;
    self.assignedProperty = nil;
}

in questo modo puoi avere un codice che ha meno ripetizioni poiché il codice sintetizzato si occuperà delle tue uscite per te.

Modifica: dovrei sottolineare che le tue proprietà non possono essere di sola lettura o altrimenti ricevi errori del compilatore per ovvi motivi :)

Altri suggerimenti

Il principio è più generale di UIView. in effetti è più generale del metodo Objective-C / Cocoa -release . È valido anche con le funzioni di memoria C malloc () / free () .

Quando non hai più bisogno di un oggetto o di una zona di memoria, prima devi rilasciarlo / liberarlo. Quindi, per assicurarti di non usarlo di nuovo, cancella i mezzi per accedere a questo oggetto o zona di memoria assegnando un nil a un oggetto o un NULL a un puntatore di memoria.

  

Qualche altro metodo potrebbe aver trattenuto la vista per qualche motivo

A meno che tu non stia invocando dealloc , viene chiamato solo quando il conteggio di mantenimento diventa zero.

Nota che in Objective-C l'invio di un messaggio a un nil " oggetto " va (spesso) perfettamente bene. In questo modo non arresterà il programma, ma il messaggio verrà semplicemente ignorato. Tuttavia, non è possibile inviare un messaggio a un oggetto liberato, che causerebbe un arresto anomalo.

Quindi, quanto segue ti darebbe un errore:

[anView release];
[anView doSomething];

Ma in realtà è ok:

[anView release];
anView = nil;
[anView doSomething];

È una questione di gusti, ma per quanto sopra, potresti in effetti preferire interrompere il programma, piuttosto che chiederti perché doSomething non viene eseguito ...

Vedi anche Invio di messaggi a zero da Introduzione a The Objective-C 2.0 Linguaggio di programmazione .

Il metodo -dealloc viene chiamato quando l'oggetto viene liberato e nessun altro metodo sull'oggetto verrà eseguito dopo. Pertanto, impostare qualsiasi variabile di istanza su zero non ha alcun effetto al di fuori di tale oggetto.

Se stavi rilasciando un oggetto (senza usare un setter) da qualche altra parte nella classe, sarebbe importante impostare la variabile di istanza su zero per impedire al codice altrove di inviare un messaggio a quell'indirizzo.

Uso molto questo schema:

- (void) showHelp: (id) sender
{
    if (helpController == nil)
    {
        helpController = [[HelpController alloc] initWithNibName: @"Help" bundle: [NSBundle mainBundle]];
    }
    [self presentModalViewController: helpController animated: YES];    
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
    [helpController release];
    helpController = nil;
}

Praticamente ovunque io alloca un viewcontroller che è modale, o altrimenti "temporaneo". In questo modo, si blocca se ne ho ancora bisogno, ma scompare se la memoria si esaurisce.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top