2010-01-25 7 views
11

So che le discussioni sugli stili di codifica tendono a finire in un disastro e in infinite guerre di fiamma, ma non è quello che voglio raggiungere. Durante l'ultimo decennio ho visto principalmente due diversi stili di codifica per i metodi dealloc in Objective-C. Il primo e il più comune era posizionare dealloc nella parte inferiore del file. Questo è anche lo stile utilizzato da Apple nei modelli predefiniti Xcode. La logica alla base di ciò sembra essere che dealloc viene richiamato quando si avvicina la fine dell'oggetto, quindi la fine del file sembra essere una bella metafora.Qual è lo stile di codifica preferito per dealloc in Objective-C?

D'altra parte un paio di persone tendono a mettere dealloc direttamente sotto le direttive @synthesize. Questo ha due grandi svantaggi a mio parere:

  1. La parte superiore del file si riempie con noioso codice.
  2. È difficile trovare le parti essenziali della classe, è necessario scorrere verso il basso.

L'enorme vantaggio a mio parere è che si dispone di una connessione visiva diretta tra proprietà e il corrispondente messaggio release.

L'altra cosa è le variabili già rilasciate Niling. Anche se non penso che ciò sia necessario, specialmente nel contesto degli oggetti in cui l'intera variabile viene scomposta dopo lo dealloc, tendo anche a zero le variabili. Sono abituato a farlo per le variabili nell'ambito della funzione, quindi sono coerente con il mio stile di codifica.

Questo è come la maggior parte delle mie classi assomigliano:

@implementation Bar 

@synthesize foo; 

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

    [super dealloc]; 
} 

// Initializers and other methods… 

ho già detto un paio di vantaggi e svantaggi. Cosa ne pensi di questo argomento? Qual è lo stile di codifica utilizzato in dealloc e perché? Ci sono altri pro e contro che ho dimenticato di menzionare?

Non voglio iniziare una guerra di fiamma qui. Voglio solo sapere quale stile usi e se hai delle ragioni specifiche per questo o se questo non ha importanza per te alla fine.

+0

Evento che tu non voglia che le persone inizino discussioni e fiamme, accadrà a domande come questa. – Younes

risposta

16

Mi piace mettere l'implementazione dealloc proprio sotto gli inizializzatori. In questo modo, quando aggiungo una nuova variabile di istanza, mi ricordo di release subito dopo I init it.

Inoltre, trovo molto utile utilizzare la direttiva #pragma mark per rendere più semplice la consultazione del file. Quindi "raggruppo" i metodi init e dealloc insieme sotto un'intestazione chiamata "inizializzatori". Quando si esplora il file, avere questi titoli rende molto più facile trovare ciò che si sta cercando senza essere distratto dal metodo dealloc.

Potrebbe essere un codice noioso, ma l'uomo è importante.

+0

I wrap initializer (s) + dealloc in un segno #pragma - Object Lifecycle (simile ai modelli Apple "Visualizza ciclo di vita" per UIViewController) –

5

Ho messo il mio dealloc in alto, proprio sotto le direttive @synthesize. È un codice un po 'noioso e noioso, ma un codice davvero importante, quindi ottiene la fatturazione migliore. Inoltre, essere in grado di confrontare tra le proprietà e i -releases è vitale.

-1
- (id)init{ 
    self = [super init]; 
    if(self) { 
     someVar = [[NSMutableArray alloc] init]; 
     // something like the following shouldn't be released: 
     someString = [NSString stringWithFormat:@"ANumber: %d",10]; 
    } 
    return self; 

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

questo è il mio modo di farlo :)

+4

Sono abbastanza sicuro che stringWithFormat restituisce un oggetto autoreleased. È necessario mantenerlo in init e rilasciarlo in dealloc. Inoltre, le parentesi non bilanciano ... – walkytalky

+0

leggere per favore, qualcosa come il seguente non dovrebbe essere rilasciato come dichiaro nel mio commento nel codice, quello che intendevo con questo è che l'oggetto che sto usando è autoreleased. –

+0

L'invio di messaggi a self all'interno di dealloc è, per lo meno, una pessima pratica! –

10

Non impostare l'Ivar a zero in dealloc se non si dispone di un motivo specifico per. Non serve a nulla e al massimo gli errori di programmatore di maschere che faresti meglio a scoprire che a nascondere.

+1

+1: non impostando le variabili di istanza su 'nil' e usando il buon vecchio 'NSZombieEnabled', ho notato alcuni errori logici nel corso degli anni che non avrei mai trovato altrimenti. – Alex

3

L'ho messo in fondo. Questo mi consente di colpire semplicemente end e andare ad esso quando aggiungo qualcosa che necessita di deallocazione. Inoltre, non lo voglio attorno ai miei sintetizzatori di proprietà, perché questo è ingannevole. Non tutto ciò che ho dealloc ha necessariamente un accessorio sintetizzato collegato ad esso. Diamine, non è nemmeno necessariamente tutto nell'inizializzatore. Se provo a usare una scorciatoia in questo modo, probabilmente lo rovinerò.

+1

concordato. Mi riferisco a tutte le variabili membro nella '@ interface' quando sto scrivendo' dealloc'. –

+0

Inoltre, finalmente, è possibile definire il blocco di ivar in @implementation rocks (ma continuo a saltare sull'intestazione e tornare indietro). –

8

Il mio ordine:

  1. sintesi e @dynamic direttive (ho iniziato a fare questi in cima a volte nel 2011; in precedenza, erano in con le implementazioni accessor)
  2. I metodi di classe (+load, +initialize, +sharedFoo, altri)
  3. initializers
  4. dealloc
  5. finalize
  6. implementazioni accessor personalizzate
  7. metodi di conformità
  8. protocollo, raggruppate per protocollo (di solito con #pragma mark direttive)
  9. metodi del gestore di notifica (di solito dichiarati in un'estensione di classe nella parte superiore)
  10. altri metodi (solitamente dichiarati nel un'estensione classe nella parte superiore)

All'interno del metodo dealloc:

  • Non utilizzare i messaggi di accesso, impliciti (accesso alle proprietà) o espliciti. Qualsiasi accesso personalizzato impuro potrebbe non essere sicuro per chiamare un oggetto parzialmente deallocato. (Lo stesso vale per gli inizializzatori.)
  • Non impostare ivars su nil. L'oggetto è parzialmente deallocato; perché stai ancora inviando messaggi? (Se non lo sei, niente sta guardando i valori degli ivars.)
  • (Se fosse in qualche modo appropriato impostare ivars su nil) Non abusare dell'operatore virgola. Un'espressione come [foo release], foo = nil mescola i tipi (prima void dall'espressione del messaggio, quindi id dall'espressione di assegnazione). Queste sono dichiarazioni separate; scrivili come tali

  • [super dealloc] è sempre l'ultimo e ha sempre una linea vuota sopra di esso, sottolineando la sua presenza.

Naturalmente, ho anche attivato "Considera gli avvisi come errori", quindi se dimentico [super dealloc], interrompo la mia build.

+1

Questi sono molti buoni consigli per migliorare uno stile di codifica Objective-C. Grazie per aver condiviso tutti loro. So che è inutile impostare i puntatori su 'nil' dopo averli rilasciati in' dealloc'. Lo faccio solo perché sono abituato a farlo in un contesto di metodo. Io uso anche una riga vuota sopra '[super dealloc]' per enfatizzare l'importanza. Una cosa interessante è che sintetizzi le tue proprietà tra i metodi. Hai una ragione specifica per questo? –

+1

È un artefatto storico: prima delle proprietà, tutti gli accessor erano personalizzati e non li ho sempre dichiarati nell'intestazione. Quindi, la definizione sarebbe la prima che il compilatore sentisse di loro, quindi non potevo usarli prima o il compilatore si lamenterebbe a ragione. Quindi, questi accessor non dichiarati dovevano essere definiti prima di tutto ciò che li poteva usare. Ora sintetizzo quasi tutti i miei accessor, ma la mia scelta di posizionamento continua. –

+0

Al giorno d'oggi, sintetizzo nella parte superiore dell'implementazione, appena sotto qualsiasi variabile di istanza esplicita. In questo modo, tutte le variabili di istanza, esplicite e sintetizzate, sono insieme e disponibili in tutta la classe, compresi gli inizializzatori e 'dealloc'. –

Problemi correlati