¿Cuándo debo usar nil y NULL en Objective-C?

170

Este es un código de muestra:

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]");

¿Cuándo debo usar nil, NULL y [NSNull null]?

Biranchi
fuente
44
Está relacionado con la pregunta del objetivo C.
Biranchi
nilsignifica una especie de NULLinstancia objc. Por lo tanto, puede marcar un valor específico para la instancia objc o el puntero genérico. En vista de la gestión de tipos y la seguridad, esto le ayudará mucho.
eonil
44
nily null/ NULLson iguales, ambos definidos como cero. Como formalidad, úsela nilal codificar Objective-C y NULLal codificar declaraciones / llamadas regulares de C / C ++. NSNullSin embargo, es algo completamente diferente. Es un objeto singleton que sirve como marcador de posición para representar "nada" en, por ejemplo, NSDictionarys donde no se permiten punteros nulos / nulos.
Hot Licks
Consulte el enlace para obtener una buena explicación [aquí] [1] [1]: stackoverflow.com/questions/5908936/…
Ameer
1
posible duplicado de NULL vs nil en Objective-C
awiebe

Respuestas:

114

Puede usar nilen cualquier lugar que pueda usar null. La principal diferencia es que puede enviar mensajes nil, por lo que puede usarlo en algunos lugares donde nullno puede trabajar.

En general, solo use nil.

Alex
fuente
12
técnicamente, son exactamente iguales, puede enviar mensajes tanto a nulo como a NULL. Idiomáticamente, aunque nil se usa generalmente para representar un objeto
cobbal
41
también, en MacTypes.h hay#define nil NULL
cobbal
8
Sí, como dice cobbal, son lo mismo. Es más una referencia contextual donde NULL es un puntero a 0x0, nil es un objeto objetivo-c inexistente y Nil es una clase objetivo-c inexistente, pero técnicamente todos son solo 0. Además, es NULL no nulo: nulo está en Java o C # pero no en Objective-C.
Jason Coco
16
Esta respuesta aceptada no reconoce que [NSNull null]es una bestia muy diferente. Para citar de NSNull Class Reference , "La clase NSNull define un objeto singleton usado para representar valores nulos en objetos de colección (que no permiten valores nulos)". Consulte también la sección Uso de NSNull en Temas de programación
Rob
"La principal diferencia es que puede enviar mensajes a cero", también puede enviar mensajes a ellos NULL.
313

Se diferencian en sus tipos. Todos son cero, pero NULLes un void *, niles un idy Niles un puntero de clase.

revs NSResponder
fuente
14
Mejor explicación que han oído hablar de la diferencia (:. Gracias
Jacob
3
Esta debería ser la respuesta aceptada, no porque haya más votos positivos, sino porque tiene la mejor explicación a la pregunta planteada.
James Mertz
55
Descripción elegante de NULLv nil, pero esto realmente pierde la marca re [NSNull null]. Consulte la sección Uso de NSNull en Temas de programación de números y valores y Referencia de clase NSNull .
Rob
Ambos parecen ser punteros a void *. Una respuesta diferente aquí ya menciona esto, pero si profundizas objc.h, encontrarás la línea #define nill __DARWIN_NULL.
gkb0986
1
Esta respuesta suena bien, pero según las otras respuestas es simplemente incorrecta.
n13
30

nil es un valor vacío enlazado / correspondiente con un objeto (el tipo de identificación en Objective-C). nil no tiene referencia / dirección, solo un valor vacío.

NSString *str = nil;

Por lo tanto, debe usarse nil si se trata de un objeto.

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

Ahora NULL se usa para el puntero sin objeto (como un puntero en C) en Objective-C. Como nil , NULL no tiene valor ni dirección.

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

Entonces, si hay una situación, cuando necesito verificar que mi estructura (variable de tipo de estructura) está vacía o no, usaré:

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

Tengamos otro ejemplo, el

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

En la observación de valores clave , el contexto debe ser un puntero en C o una referencia de objeto. Aquí para el contexto no podemos usar nil ; Tenemos que usar NULL .

Finalmente, la clase NSNull define un objeto singleton usado para representar valores nulos en objetos de colección (NSArray, NSDictionary). El [NSNull nulo] voluntad devuelve la instancia singleton de NSNull. Básicamente [NSNull null] es un objeto apropiado.

No hay forma de insertar un objeto nulo en un objeto de tipo colección. Veamos un ejemplo:

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

En la segunda línea, no obtendremos ningún error, porque es perfectamente justo insertar un objeto NSNull en un objeto de tipo colección. En la tercera línea, obtendremos el error "el objeto no puede ser nulo". Porque nulo no es un objeto.

Shad
fuente
+1 por mencionar el uso práctico de nil / null en la matriz.
Michael
19

NULL y nil son iguales entre sí, pero nil es un valor de objeto, mientras que NULL es un valor de puntero genérico ( (void*)0, para ser específico). [NSNull null]es un objeto destinado a ser nulo en situaciones en las que no está permitido. Por ejemplo, no puede tener un valor nulo en un NSArray. Entonces, si necesita representar un "nulo", puede usarlo [NSNull null].

Chuck
fuente
12

He encontrado lo siguiente:

objc.h

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

_tipos.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 */

Por su aspecto, no hay diferencia sino conceptual.

Colnaghi
fuente
8

Cuidado con que if([NSNull null])vuelve true.

Nicolas Manzini
fuente
7

Ambos son solo de tipo cero. Funcionalmente, no hay diferencia entre ellos. es decir.,

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

Hay una diferencia, pero solo para usted y otros humanos que leen el código, al compilador no le importa.

Una cosa más nula es un valor de objeto, mientras que NULL es un valor de puntero genérico.

Nirav
fuente
6

En los modernos SDK de OS X e iOS:

  • nil y Nil y NULLson idénticos en Objective-C y en Objective-C ++ antes de C ++ 11.
  • nil y Nil y std::nullptrson idénticos en Objective-C ++ con C ++ 11.

Estilísticamente, muchas personas prefieren usar nilpara objetos Objective-C y / NULLonullptr para otros tipos de punteros. Yo mismo ahora uso en niltodas partes.

[NSNull null]es un objeto singleton utilizado para representar valores nulos en situaciones donde nilestá prohibido como un valor (generalmente en un objeto de colección como un NSArrayo NSDictionary). Temas de programación de números y valores: uso de NSNull

Greg Parker
fuente
5

Para ampliar un comentario de @cobbal:

MacTypes.h contiene:

#ifndef nil
   #define nil NULL
#endif
Justin Tanner
fuente
4

Como ya se mencionó, son iguales, pero uso uno u otro dependiendo del idioma en el que se escribió el marco correspondiente.

Para todo lo relacionado con Objective-C, uso nil. Por ejemplo:

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

    // process elements
    ...
}

Sin embargo, cuando verifico la validez de los modelos de datos desde un marco C (como el marco de AddressBook y CoreFoundation), uso NULL. Por ejemplo:

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

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

De esta manera, tengo pistas sutiles en mi código si estoy tratando con código basado en Obj-C o C.

Tafkadasoh
fuente
4

nil es un puntero de objeto a nada. Aunque son semánticamente distintos de NULL , son técnicamente equivalentes entre sí.

En el nivel de marco, Foundation define NSNull , que define un método de clase, + null, que devuelve el objeto Singleton NSNull. NSNull es diferente de nil o NULL , ya que es un objeto real , en lugar de un valor cero.

Además, en Foundation / NSObjCRuntime.h, Nil se define como un puntero de clase a la nada.

Consulte esto para obtener más información: nil / Nil / NULL / NSNull

Shubham Jain
fuente
3

Hay una diferencia en algunos contextos.

Literalmente, Null es un personaje: ASCII 0.

Nil es equivalente a blanco, sin valor.

Dependiendo del contexto de programación, esto puede ser una gran diferencia.

Pastel de carne
fuente
1

Utilice NULL, por ejemplo, cuando invoque un método Objective-C con un parámetro de salida de tipo (NSError **).

Veo muchos códigos de ejemplo en la web donde las personas proporcionan nulo en lugar de NULL en este caso. Esto se debe a que es un puntero a un puntero y, por lo tanto, no es directamente un tipo de objeto Objective-C. Como se dijo anteriormente, nil debe usarse para los tipos de objeto Objective-C.

Peter Mortensen
fuente
1

Básicamente: nil: puntero nulo en un objeto y nulo: es para otro tipo de puntero

gerachev
fuente
0

nil significa ausencia de valor mientras NULL representa No Object,

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

Aquí [NSNULL null] es un objeto que significa que no hay ningún objeto, al mismo tiempo no puede agregar nil para indicar la ausencia de objeto.

también puede usar nil y [NSNUll null] para verificar.

Roshan Sah
fuente
0

Esto lo ayudará a comprender la diferencia entre nulo, nulo y nulo.

El siguiente enlace puede ayudarlo de alguna manera:

http://nshipster.com/nil/

nil -> valor nulo literal para objetos Objective-C.

Nil -> valor nulo literal para las clases Objective-C.

NULL -> valor nulo literal para punteros en C.

NSNULL -> objeto singleton usado para representar nulo.

Subhakar Prabhu
fuente
¿Esto agrega algo nuevo (que no está cubierto por las respuestas existentes)?
Florian Koch