2011-12-18 6 views
34

Ho visto spesso "asserire" nel codice iOS, lo ho cercato su google, e ho avuto modo di sapere che è vero o falso.Come sapere se NSAssert è disabilitato nelle versioni di rilascio?

Voglio sapere se questo si disabiliterà automaticamente in modalità di rilascio?

+2

È, francamente, un design pazzesco che afferma di non essere disattivato nelle versioni di rilascio per impostazione predefinita. Vola di fronte a ogni altro compilatore C che conosco. –

+0

@SevaAlekseyev Siamo d'accordo, abbiamo avuto uno shock quando le asserzioni sono ancora arrivate in Release. Completamente non convenzionale. La nostra filosofia è "fallire velocemente nello sviluppo, morire duramente nella produzione". –

risposta

38

Utilizzare NSAssert() e i relativi companion.

nel progetto definiscono NS_BLOCK_ASSERTIONS per la configurazione di rilascio.

I tremoletti Xcode 4 disabilitano NSAsserts nella configurazione di rilascio. Aggiunge

-DNS_BLOCK_ASSERTIONS=1 

a "Altri flag C" per "Rilascio".

Dalla documentazione:

affermazioni sono disabilitate se è definito il preprocessore macro NS_BLOCK_ASSERTIONS.

La macro NSAssert valuta la condizione e funge da front-end del gestore di assertion.

Ogni thread ha il proprio gestore di asserzione, che è un oggetto della classe NSAssertionHandler. Quando viene richiamato, un gestore di asserzioni stampa un messaggio di errore che include i nomi di metodi e classi (o il nome della funzione). Quindi solleva un'eccezione NSInternalInconsistencyException. Se la condizione viene valutata su NO, la macro richiama handleFailureInMethod:object:file:lineNumber:description: sul gestore assertion per il thread corrente, passando desc come stringa di descrizione.

Questa macro deve essere utilizzata solo con i metodi Objective-C.

4

Gli avvisi vengono compilati in modo condizionato dal codice quando viene definito NDEBUG. Se si definisce NDEBUG=1 nella corrispondente sezione delle impostazioni di compilazione, si disattiveranno gli asserzioni nel proprio codice indipendentemente dalla modalità di rilascio o di debug.

24

io sarò qui fornire una meta-risposta:

Sia @CocoaFu e @dasblinkenlight sono corretti. NS_BLOCK_ASSERTIONS disattiva NSAssert() e NDEBUG si spegne assert(). Hai bisogno di entrambi se li usi entrambi.

+0

Leggere iOS 5 Programmazione da @Rob: Prendilo, leggilo, Programmalo meglio su iOS 5. – zaph

+0

Sfortunatamente, nel tuo riassunto delle due parole pronunciate erroneamente. – Ant

+1

Notato e risolto. NSDEBUG-> NDEBUG –

7

Come detto da Zaph -DNS_BLOCK_ASSERTIONS=1 è impostato per il rilascio. Tuttavia, se si desidera verificare questo.

Prima osservare nei documenti che NSAssert è disabilitato dalla macro NS_BLOCK_ASSERTIONS. Quindi aggiungere questo per la costruzione e osservare è conforme ok:

#ifdef NS_BLOCK_ASSERTIONS 
#error Error - NS_BLOCK_ASSERTIONS is defined 
#endif 

quindi modificare lo schema di rilasciare (cmd - spostamento - <)

enter image description here

poi osservare che la compilazione fallisce. Pertanto, NS_BLOCK_ASSERTIONS è definito nel significato NSAssert s sono disabilitati.

0

Ora, come da Xcode 6, l'impostazione è ENABLE_NS_ASSERTIONS, che è impostata su 1 per le configurazioni di debug e 0 per rilascio, per impostazione predefinita.

È possibile optare per la build di versioni sulla riga di comando passando l'argomento ENABLE_NS_ASSERTIONS=1, che sto facendo per eseguire test di unità che verificano le condizioni di asserzione, ma altrimenti dovrebbe essere eseguito con il flag DEBUG disattivato.

26

Aggiornamento: Verificato questo funziona anche in Xcode 8.

In Xcode 7, andare nelle impostazioni di generazione del progetto e cercare "Assert" nella barra di ricerca. Mostra la sezione "Apple LLVM 7.0 - Pre-elaborazione". Esiste un'impostazione denominata "Abilita asserzioni Foundation".

Ho abilitato/disabilitato NSAssert da lì.

enter image description here

+2

che aggiunge un 'ENABLE_NS_ASSERTIONS = NO;' al file 'AppName.xcodeproj/project.pbxproj' dell'app – computingfreak

0

Ecco quello che faccio in cima alla mia main():

#if defined(NDEBUG) 
{ 
    // The assertion code below should be compiled out of existence in a release 
    // build. Log an error and abort the program if it is not. 
    bool ok = true; 
    NSCAssert(ok = false, @"NS assertions should be disabled but are not"); 
    if (!ok) 
    { 
    NSLog(@"Detected release build but NS_BLOCK_ASSERTIONS is not defined"); 
    return -1; 
    } 
} 
#endif 

Nota che, dal momento main() è una funzione C e non una funzione di Objective-C, NSCAssert viene utilizzato al di sopra piuttosto che NSAssert . (NSAssert è valido)

Problemi correlati