objective-c - libro - objective c or swift
¿Cuándo debería usar nil y NULL en Objective-C? (16)
Ambos son solo tipo cero. Funcionalmente, no hay diferencia entre ellos. es decir.,
#define NULL ((void*)0)
#define nil ((id)0)
Hay una diferencia, pero solo para ti y otros humanos que leen el código, al compilador no le importa.
Una cosa más nil es un valor de objeto mientras que NULL es un valor de puntero genérico.
Este es el 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 debería usar nil, NULL y [NSNull null]?
Básicamente: nil: puntero nulo en un objeto y nulo: es para otro tipo de puntero
Como ya se mencionó, son lo mismo, pero utilizo uno u otro según el 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, al verificar la validez de los modelos de datos de un C-framework (como AddressBook framework 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.
Difieren en sus tipos. Todos son cero, pero NULL
es un void *
, nil
es una id
y Nil
es un puntero de clase.
En los SDK OS X e iOS modernos:
-
nil
yNil
yNULL
son idénticos en Objective-C y en Objective-C ++ antes de C ++ 11. -
nil
yNil
ystd::nullptr
son idénticos en Objective-C ++ con C ++ 11.
Estilísticamente, muchas personas prefieren usar nil
para objetos Objective-C y NULL
o nullptr
para otros tipos de punteros. Yo mismo ahora uso nil
todas partes.
[NSNull null]
es un uso de objeto singleton para representar valores nulos en situaciones donde nil
está prohibido como valor (normalmente en un objeto de colección como NSArray
o NSDictionary
). Temas de programación de valores y valores: uso de NSNull
Esto te ayudará a entender la diferencia entre nil, NIL y null.
El siguiente enlace puede ayudarte de alguna manera:
nil -> literal valor nulo para objetos Objective-C.
Nil -> valor literal nulo para las clases Objective-C.
NULL -> valor literal nulo para punteros en C.
NSNULL -> objeto singleton utilizado para representar nulo.
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.
He encontrado lo siguiente:
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 */
Por la forma en que se ve, no hay diferencia, sino conceptual.
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 que debe representar nulo en situaciones donde nil no está permitido. Por ejemplo, no puede tener un valor nulo en un NSArray. Entonces, si necesita representar un "nil", puede usar [NSNull null]
.
Puedes usar nil
en cualquier lugar donde puedas usar null
. La principal diferencia es que puede enviar mensajes a nil
, para que pueda usarlo en algunos lugares donde null
no funciona.
En general, solo usa nil
.
Tenga cuidado de que if([NSNull null])
devuelva true
.
Utilice NULL, por ejemplo, cuando invoque un método Objective-C con un parámetro de salida de tipo (NSError **).
Veo muchos ejemplos de código en la web donde las personas proporcionan nil en lugar de NULL en este caso. Esto se debe a que es un puntero a un puntero y, por lo tanto, no directamente a un tipo de objeto Objective-C. Como se dijo anteriormente, nil debería usarse para tipos de objetos Objective-C.
nil significa ausencia de valor mientras que NULL representa No Object,
NSArray * array = @ [@ "¡Hola mundo!", @ 101, [NSNULL nulo]];
Aquí [NSNULL null] es un objeto que no significa ningún objeto, al mismo tiempo no se puede agregar nil para indicar la ausencia de objeto.
puede usar tanto nil como [NSNUll null] para verificar también.
nil es un puntero de objeto a nada. Aunque semánticamente distinto 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 NSNull singleton. NSNull es diferente de nulo o NULO , ya que es un objeto real , en lugar de cero.
Además, en Foundation / NSObjCRuntime.h, Nil se define como un puntero de clase a nada.
nil es un valor vacío enlazado / correspondiente con un objeto (el tipo de id en el Objetivo-C). nil no tiene referencia / dirección, solo un valor vacío.
NSString *str = nil;
Así que no debería usarse, si estamos tratando con un objeto.
if(str==nil)
NSLog("str is empty");
Ahora NULL se usa para el puntero que no es objeto (como un puntero C) en Objective-C. Como nulo , 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
De la observación de valores clave , el contexto debe ser un puntero 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 utilizado para representar valores nulos en objetos de colección (NSArray, NSDictionary). El [NSNull null] devolverá la instancia singleton de NSNull. Básicamente [NSNull null] es un objeto adecuado.
No hay forma de insertar un objeto nil 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 tipo colección. En la tercera línea, obtendremos el error "el objeto no puede ser nulo". Porque nil no es un objeto.