Quando devo usar nulo e NULL no Objective-C?

170

Este é um código de exemplo:

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 devo usar nulo, NULL e [NSNull null]?

Biranchi
fonte
4
Está relacionado à questão do Objetivo C.
22909 Biranchi
nilsignifica um tipo de NULLinstância objc. Assim, você pode marcar que um valor específico se destina a instância objc ou ponteiro genérico. Em vista do gerenciamento e segurança do tipo, isso o ajudará muito.
eonil
4
nile null/ NULLsão os mesmos - ambos definidos como zero. Como formalidade, use nilao codificar Objective-C e NULLao codificar declarações / chamadas regulares em C / C ++. NSNullé algo totalmente diferente, no entanto. É um objeto singleton que serve como um espaço reservado para representar "nada" em, por exemplo, NSDictionarys onde indicadores nulos / nulos não são permitidos.
Hot Licks
Consulte o link para obter uma boa explicação [aqui] [1] [1]: stackoverflow.com/questions/5908936/…
Ameer
1
possível duplicado de NULL vs nula em Objective-C
awiebe

Respostas:

114

Você pode usar nilem qualquer lugar que possa usar null. A principal diferença é que você pode enviar mensagens para nil, para que você possa usá-lo em alguns lugares onde nullnão é possível trabalhar.

Em geral, basta usar nil.

Alex
fonte
12
tecnicamente, eles são exatamente iguais, você pode enviar mensagens para nulo e para NULL. Idiomaticamente embora nulo é geralmente usado para representar um objeto
cobbal
41
Além disso, em MacTypes.h existe#define nil NULL
cobbal
8
Sim, como diz Cobbal, eles são os mesmos. É mais uma referência contextual em que NULL é um ponteiro para 0x0, nil é um objeto objetivo-c inexistente e Nil é uma classe objetivo-c inexistente, mas tecnicamente eles são todos apenas 0. Além disso, é NULL não null - null está em Java ou C #, mas não em Objective-C.
Jason Coco
16
Essa resposta aceita falha em reconhecer que [NSNull null]é uma fera muito diferente. Para citar a Referência da classe NSNull , "A classe NSNull define um objeto singleton usado para representar valores nulos em objetos de coleção (que não permitem valores nulos)". Consulte também a seção Usando o NSNull dos Tópicos de programação
Rob
"A principal diferença é que você pode enviar mensagens para zero" - você também pode enviar mensagens NULL.
313

Eles diferem em seus tipos. Eles são todos zero, mas NULLé um void *, nilé um ide Nilé um ponteiro de Classe.

NSResponder
fonte
14
Melhor explicação que eu ouvi falar da diferença (:. Graças
Jacob
3
Essa deve ser a resposta aceita, não porque haja mais votos positivos, mas porque ela tem a melhor explicação para a pergunta.
precisa
5
Descrição elegante de NULLv nil, mas isso erra seriamente a marca re [NSNull null]. Consulte a seção Usando o NSNull de Tópicos de programação de número e valor e Referência de classe do NSNull .
Rob
Ambos parecem ser indicadores de void *. Uma resposta diferente aqui já menciona isso, mas se você se aprofundar objc.h, encontrará a linha #define nill __DARWIN_NULL.
Gkb0986
1
Essa resposta parece boa, mas de acordo com as outras respostas, é simplesmente incorreta.
n13 26/03/14
30

nil é um valor vazio vinculado / correspondente a um objeto (o tipo de ID em Objective-C). nulo não tem referência / endereço, apenas um valor vazio.

NSString *str = nil;

Portanto, nada deve ser usado, se estivermos lidando com um objeto.

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

Agora NULL é usado para ponteiro não-objeto (como um ponteiro C) em Objective-C. Como nulo , NULL não tem valor nem endereço.

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

Portanto, se houver uma situação, quando eu precisar verificar se minha struct (variável de tipo de estrutura) está vazia ou não, usarei:

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

Vamos dar outro exemplo, o

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

Da observação do valor-chave , o contexto deve ser um ponteiro C ou uma referência a objeto. Aqui, para o contexto, não podemos usar nada ; nós temos que usar NULL .

Finalmente, a classe NSNull define um objeto singleton usado para representar valores nulos em objetos de coleção (NSArray, NSDictionary). O [NSNull null] retornará a instância singleton do NSNull. Basicamente [NSNull null] é um objeto adequado.

Não há como inserir um objeto nulo em um objeto do tipo coleção. Vamos dar um exemplo:

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

Na segunda linha, não obteremos nenhum erro, porque é perfeitamente justo inserir um objeto NSNull em um objeto do tipo coleção. Na terceira linha, obteremos o erro "o objeto não pode ser nulo". Porque nulo não é um objeto.

Shad
fonte
+1 por mencionar o uso prático de nulo / nulo na matriz.
Michael Michael
19

NULL e nil são iguais entre si, mas nil é um valor de objeto enquanto NULL é um valor genérico de ponteiro ( (void*)0, para ser específico). [NSNull null]é um objeto destinado a substituir nada em situações em que nada é permitido. Por exemplo, você não pode ter um valor nulo em um NSArray. Portanto, se você precisar representar um "zero", poderá usar [NSNull null].

Chuck
fonte
12

Encontrei o seguinte:

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

Do jeito que parece, não há diferença, a não ser conceitual.

Colnaghi
fonte
8

Cuidado com o if([NSNull null])retorno true.

Nicolas Manzini
fonte
7

Ambos são apenas zero de zero. Funcionalmente, não há diferença entre eles. ie.,

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

Há uma diferença, mas apenas para você e outros humanos que lêem o código, o compilador não se importa.

Mais uma coisa nil é um valor de objeto, enquanto NULL é um valor genérico de ponteiro.

Nirav
fonte
6

Nos modernos OS X e iOS SDKs:

  • nile Nile NULLsão idênticos em Objective-C e em Objective-C ++ antes C ++ 11.
  • nile Nile std::nullptrsão idênticos em Objective-C ++ com C ++ 11.

Estilisticamente, muitas pessoas preferem usar nilpara objetos Objective-C e / NULLou nullptrpara outros tipos de ponteiros. Eu mesmo agora uso em niltodos os lugares.

[NSNull null]é um objeto singleton usado para representar valores nulos em situações em que nilé proibido como um valor (geralmente em um objeto de coleção como um NSArrayou NSDictionary). Tópicos de programação de número e valor: Usando o NSNull

Greg Parker
fonte
5

Para expandir um comentário de @cobbal:

MacTypes.h contém:

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

Como já mencionado, eles são os mesmos, mas eu uso um ou outro, dependendo do idioma em que a estrutura correspondente foi escrita.

Para tudo relacionado ao Objective-C, eu uso zero. Por exemplo:

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

    // process elements
    ...
}

No entanto, ao verificar a validade dos modelos de dados de uma estrutura C (como a estrutura AddressBook e CoreFoundation), uso NULL. Por exemplo:

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

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

Dessa forma, tenho dicas sutis no meu código se estiver lidando com código baseado em Obj-C ou C.

Tafkadasoh
fonte
4

nil é um ponteiro de objeto para nada. Embora semanticamente distintos de NULL , eles são tecnicamente equivalentes um ao outro.

No nível da estrutura, o Foundation define NSNull , que define um método de classe, + null, que retorna o objeto NSNull singleton. NSNull é diferente de nulo ou NULL , pois é um objeto real , em vez de um valor zero.

Além disso, no Foundation / NSObjCRuntime.h, Nil é definido como um ponteiro de classe para nada.

Consulte isto para mais informações - nil / Nil / NULL / NSNull

Shubham Jain
fonte
3

Há uma diferença em alguns contextos.

Literalmente, Nulo é um caractere: ASCII 0.

Zero é equivalente a branco, sem valor.

Dependendo do contexto de programação, isso pode ser uma grande diferença.

Rolo de carne
fonte
1

Use NULL, por exemplo, quando você chama um método Objective-C com um parâmetro de saída do tipo (NSError **).

Eu vejo muitos exemplos de código na web em que as pessoas fornecem zero em vez de NULL nesse caso. Isso ocorre porque é um ponteiro para um ponteiro e, portanto, não é diretamente um tipo de objeto Objective-C. Como dito acima, nada deve ser usado para os tipos de objeto Objective-C.

Peter Mortensen
fonte
1

Basicamente: nil: ponteiro nulo em um objeto e null: é para outro ponteiro de tipo

gerachev
fonte
0

nulo significa ausência de valor, enquanto NULL representa No Object,

NSArray * array = @ [@ "Olá, mundo!", @ 101, [NSNULL null]];

Aqui [NSNULL null] é um objeto que não significa objeto; ao mesmo tempo, você não pode adicionar nada para indicar ausência de objeto.

você pode usar nulo e [NSNUll null] para verificar também.

Roshan Sah
fonte
0

Isso ajudará você a entender a diferença entre zero, NIL e nulo.

O link abaixo pode ajudá-lo de alguma forma:

http://nshipster.com/nil/

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

Nulo -> valor nulo literal para as classes Objective-C.

NULL -> valor nulo literal para ponteiros C.

NSNULL -> objeto singleton usado para representar nulo.

Subhakar Prabhu
fonte
isso adiciona algo novo (que não é coberto pelas respostas existentes)?
Florian Koch