Quando dovrei usare zero e NULL in Objective-C?


170

Questo è un codice di esempio:

NSDictionary *myDictionary = [NSDictionary dictionary];
NSNumber *myNumber = [myDictionary valueForKey: @"MyNumber"];
NSLog(@"myNumber = %@", myNumber); // output myNumber = (null)

if (myNumber == nil)
    NSLog(@"test 1 myNumber == nil");

if (myNumber == NULL)
    NSLog(@"test 2 myNumber == NULL");

if ([myNumber isEqual:[NSNull null]])
    NSLog(@"test 3 myNumber == [NSNull null]");

Quando dovrei usare zero, NULL e [NSNull null]?


4
Relativo alla domanda dell'obiettivo C.
Biranchi,

nilsignifica una specie di NULLper esempio objc. Quindi è possibile contrassegnare un valore specifico destinato all'istanza di objc o al puntatore generico. In vista della gestione del tipo e della sicurezza, questo ti aiuterà molto.
eonil,

4
nile null/ NULLsono uguali - entrambi definiti come zero. Come formalità, utilizzare nilquando si codifica Objective-C e NULLquando si codificano le normali istruzioni / chiamate C / C ++. NSNullè qualcosa di completamente diverso, tuttavia. È un oggetto singleton che funge da segnaposto per rappresentare "nulla" in, ad esempio, NSDictionarys in cui non sono consentiti puntatori nil / null.
Hot Licks

Fai riferimento al link per una buona spiegazione [qui] [1] [1]: stackoverflow.com/questions/5908936/…
Ameer,

1
possibile duplicato di NULL vs zero in Objective-C
awiebe

Risposte:


114

Puoi usare nilovunque tu possa usare null. La differenza principale è che puoi inviare messaggi a nil, quindi puoi usarlo in alcuni posti dove non nullposso lavorare.

In generale, basta usare nil.


12
tecnicamente, sono esattamente uguali, puoi inviare messaggi sia a zero che a NULL. Idiomaticamente, sebbene lo zero sia solitamente usato per rappresentare un oggetto
ciottoli alle 05:43

41
inoltre, in MacTypes.h c'è#define nil NULL
cobbal

8
Sì, come dice il cobbal, sono gli stessi. È più un riferimento contestuale in cui NULL è un puntatore a 0x0, nil è un oggetto obiettivo-c inesistente e Nil è una classe obiettivo-c inesistente, ma tecnicamente sono tutti solo 0. Inoltre, è NULL non null - null è in Java o C # ma non in Objective-C.
Jason Coco,

16
Questa risposta accettata non riconosce che [NSNull null]è una bestia molto diversa. Per citare il riferimento alla classe NSNull , "La classe NSNull definisce un oggetto singleton utilizzato per rappresentare valori null negli oggetti di raccolta (che non consentono valori nulli)." Vedere anche la sezione Utilizzo di NSNull degli argomenti di programmazione
Rob,

"La differenza principale è che puoi inviare messaggi a zero" - puoi anche inviare messaggi NULL.

313

Differiscono nei loro tipi. Sono tutti zero, ma NULLè un void *, nilè un ided Nilè un puntatore di classe.


14
La migliore spiegazione che ho sentito della differenza (: Grazie.
Jacob,

3
Questa dovrebbe essere la risposta accettata, non perché ci siano più voti positivi, ma perché ha la migliore spiegazione alla domanda posta.
James Mertz,

5
Elegante descrizione di NULLv nil, ma questo manca seriamente il segno [NSNull null]. Vedere la sezione Utilizzo di NSNull in Argomenti di programmazione di numeri e valori e Riferimenti alla classe NSNull .
Rob,

Entrambi sembrano essere dei suggerimenti void *. Una risposta diversa qui menziona già questo, ma se scavi in objc.h, troverai la linea #define nill __DARWIN_NULL.
gkb0986,

1
Questa risposta suona bene ma secondo le altre risposte è semplicemente errata.
n13,

30

nil è un valore vuoto associato / corrispondente a un oggetto (il tipo id in Objective-C). zero non ha alcun riferimento / indirizzo, solo un valore vuoto.

NSString *str = nil;

Quindi dovrebbe essere usato lo zero, se abbiamo a che fare con un oggetto.

if(str==nil)
    NSLog("str is empty");

Ora NULL viene utilizzato per il puntatore non oggetto (come un puntatore C) in Objective-C. Come zero , NULL non ha valore né indirizzo.

char *myChar = NULL;
struct MyStruct *dStruct = NULL;

Quindi, se c'è una situazione, quando devo controllare che la mia struttura (variabile del tipo di struttura) sia vuota o no, userò:

if (dStruct == NULL)
    NSLog("The struct is empty");

Facciamo un altro esempio, il

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

Nell'osservazione del valore-chiave , il contesto dovrebbe essere un puntatore C o un riferimento a un oggetto. Qui per il contesto non possiamo usare zero ; dobbiamo usare NULL .

Infine, la classe NSNull definisce un oggetto singleton utilizzato per rappresentare valori null negli oggetti di raccolta (NSArray, NSDictionary). Il [NSNull null] I ritorni saranno l'istanza Singleton NSNull. Fondamentalmente [NSNull null] è un oggetto appropriato.

Non è possibile inserire un oggetto nil in un oggetto di tipo raccolta. Facciamo un esempio:

NSMutableArray *check = [[NSMutableArray alloc] init];
[check addObject:[NSNull null]];
[check addObject:nil];

Sulla seconda riga, non avremo alcun errore, poiché è perfettamente corretto inserire un oggetto NSNull in un oggetto di tipo raccolta. Sulla terza riga, otterremo l'errore "L'oggetto non può essere nullo". Perché zero non è un oggetto.


+1 per menzionare l'uso pratico di zero / null in array.
Michael,

19

NULL e nil sono uguali tra loro, ma nil è un valore oggetto mentre NULL è un valore puntatore generico ( (void*)0, per essere precisi). [NSNull null]è un oggetto destinato a sostituire lo zero in situazioni in cui lo zero non è consentito. Ad esempio, non è possibile avere un valore nullo in un NSArray. Quindi, se è necessario rappresentare un "zero", è possibile utilizzare [NSNull null].


12

Ho trovato il seguente:

objc.h

#define Nil __DARWIN_NULL   /* id of Nil class */
#define nil __DARWIN_NULL   /* id of Nil instance */

_types.h

#define __DARWIN_NULL ((void *)0)

stddef.h

#undef NULL
#ifdef __cplusplus
#undef __null  // VC++ hack.
#define NULL __null
#else
#define NULL ((void*)0)
#endif

MacTypes.h

#ifndef NULL
#define NULL    __DARWIN_NULL
#endif /* ! NULL */
#ifndef nil
    #define nil NULL
#endif /* ! nil */

A quanto pare, non c'è differenza se non concettuale.



7

Entrambi sono solo zero tipografici. Funzionalmente, non c'è differenza tra loro. ie.,

#define NULL ((void*)0)
#define nil ((id)0)

C'è una differenza, ma solo a te stesso e agli altri umani che leggono il codice, al compilatore non importa.

Un'altra cosa nulla è un valore oggetto mentre NULL è un valore puntatore generico.


6

Nei moderni SDK per OS X e iOS:

  • nile Nile NULLsono identici in Objective-C e in Objective-C ++ prima di C ++ 11.
  • nile Nile std::nullptrsono identici in Objective-C ++ con C ++ 11.

Stilisticamente, molte persone preferiscono usare nilper oggetti Objective-C e NULLo nullptrper altri tipi di puntatori. Io stesso ora uso nilovunque.

[NSNull null]è un oggetto singleton utilizzato per rappresentare valori null in situazioni in cui nilè vietato come valore (in genere in un oggetto raccolta come un NSArrayo NSDictionary). Argomenti di programmazione di numeri e valori: utilizzo di NSNull



4

Come già accennato, sono gli stessi, ma io uso l'uno o l'altro a seconda della lingua in cui è stato scritto il framework corrispondente.

Per tutto ciò che riguarda Objective-C, uso zero. Per esempio:

- (BOOL)doSomethingWithObjectsInArray:(NSArray *)anArray {
    if (anArray == nil) return NO;

    // process elements
    ...
}

Tuttavia, quando controllo la validità dei modelli di dati da un C-framework (come AddressBook framework e CoreFoundation), utilizzo NULL. Per esempio:

- (BOOL)showABUnknownPersonVCForABRecordRef:(ABRecordRef)aRecord {
    if (aRecord == NULL) return NO;

    // set-up the ABUnknownPersonViewController and display it on screen
    ..
}

In questo modo, ho indizi sottili nel mio codice se ho a che fare con codice basato su Obj-C o C.


4

zero è un puntatore a nulla. Sebbene siano semanticamente distinti da NULL , sono tecnicamente equivalenti tra loro.

A livello di framework, Foundation definisce NSNull , che definisce un metodo class, + null, che restituisce l'oggetto NSNull singleton. NSNull è diverso da zero o NULL , in quanto è un oggetto reale , anziché un valore zero.

Inoltre, in Foundation / NSObjCRuntime.h, Nil è definito come un puntatore di classe a nulla.

Fare riferimento a questo per ulteriori informazioni: zero / Nil / NULL / NSNull


3

C'è una differenza in alcuni contesti.

Letteralmente, Null è un personaggio: ASCII 0.

Zero equivale a vuoto, nessun valore.

A seconda del contesto di programmazione, questa può essere una grande differenza.


1

Utilizzare NULL ad esempio quando si richiama un metodo Objective-C con un parametro di output di tipo (NSError **).

Vedo un sacco di codice di esempio sul web in cui le persone forniscono zero anziché NULL in questo caso. Questo perché è un puntatore a un puntatore e quindi non direttamente un tipo di oggetto Objective-C. Come detto sopra, zero dovrebbe essere usato per i tipi di oggetti Objective-C.


1

Fondamentalmente: nil: puntatore null su un oggetto e null: è per puntatore di altro tipo


0

zero significa assenza di valore mentre NULL rappresenta No Object,

NSArray * array = @ [@ "Hello World!", @ 101, [NSNULL null]];

Qui [NSNULL null] è un oggetto che significa nessun oggetto, allo stesso tempo non è possibile aggiungere nulla per indicare l'assenza di oggetto.

puoi usare sia nil che [NSNUll null] anche per il controllo.


0

Questo ti aiuterà a capire la differenza tra zero, NIL e null.

Il link seguente può aiutarti in qualche modo:

http://nshipster.com/nil/

nil -> valore null letterale per gli oggetti Objective-C.

Nil -> valore null letterale per le classi Objective-C.

NULL -> valore null letterale per i puntatori C.

NSNULL -> oggetto singleton usato per rappresentare null.


questo aggiunge qualcosa di nuovo (che non è coperto dalle risposte esistenti)?
Florian Koch,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.