Quand dois-je utiliser nil et NULL en Objective-C?

170

Voici un exemple de code:

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

Quand dois-je utiliser nil, NULL et [NSNull null]?

Biranchi
la source
4
C'est lié à la question de l'Objectif C.
Biranchi
nilsignifie une sorte d' NULLinstance for objc. Ainsi, vous pouvez marquer qu'une valeur spécifique est destinée à une instance objc ou à un pointeur générique. Compte tenu de la gestion des types et de la sécurité, cela vous aidera beaucoup.
eonil
4
nilet null/ NULLsont les mêmes - tous deux définis comme étant zéro. Par formalité, à utiliser nillors du codage d'Objective-C et NULLlors du codage d'instructions / d'appels C / C ++ normaux. NSNullest quelque chose d'entièrement différent, cependant. C'est un objet singleton qui sert d'espace réservé pour représenter "rien" dans, par exemple, les NSDictionary où les pointeurs nil / null ne sont pas autorisés.
Hot Licks
Reportez-vous au lien pour une bonne explication [ici] [1] [1]: stackoverflow.com/questions/5908936/…
Ameer
1
duplication possible de NULL vs nil en Objective-C
awiebe

Réponses:

114

Vous pouvez utiliser nilà peu près partout où vous pouvez utiliser null. La principale différence est que vous pouvez envoyer des messages à nil, vous pouvez donc l'utiliser dans certains endroits oùnull pas travailler.

En général, utilisez simplement nil.

Alex
la source
12
techniquement, ils sont exactement égaux, vous pouvez envoyer des messages à la fois à nil et à NULL. Idiomatiquement bien que nul soit généralement utilisé pour représenter un objet
cobbal
41
aussi, dans MacTypes.h il y a#define nil NULL
cobbal
8
Ouais, comme le dit Cobbal, ce sont les mêmes. C'est plus une référence contextuelle où NULL est un pointeur vers 0x0, nil est un objet objective-c inexistant et Nil est une classe objective-c inexistante, mais techniquement, ils sont tous juste 0. De plus, ce n'est pas NULL null - null est en Java ou C # mais pas en Objective-C.
Jason Coco
16
Cette réponse acceptée ne reconnaît pas qu'il [NSNull null]s'agit d'une bête très différente. Pour citer la référence de classe NSNull , «La classe NSNull définit un objet singleton utilisé pour représenter les valeurs nulles dans les objets de collection (qui n'autorisent pas les valeurs nulles)». Consultez également la section Utilisation de NSNull des rubriques de programmation des nombres et des valeurs.
Rob
"La principale différence est que vous pouvez envoyer des messages à zéro" - vous pouvez également envoyer des messages à NULL.
313

Ils diffèrent dans leurs types. Ils sont tous nuls, mais NULLest un void *, nilest un idet Nilest un pointeur de classe.

NSResponder
la source
14
Meilleure explication que j'ai entendu parler de la différence (: Merci.
Jacob
3
Telle devrait être la réponse acceptée, non pas parce qu'il y a plus de votes positifs, mais parce qu'elle a la meilleure explication à la question posée.
James Mertz
5
Description élégante de NULLv nil, mais cela manque sérieusement la marque re [NSNull null]. Consultez la section Utilisation de NSNull des rubriques de programmation de nombres et de valeurs et Référence de classe NSNull .
Rob
Les deux semblent être des pointeurs vers void *. Une réponse différente ici mentionne déjà cela, mais si vous creusez objc.h, vous trouverez la ligne #define nill __DARWIN_NULL.
gkb0986
1
Cette réponse semble bonne, mais selon les autres réponses, elle est tout simplement incorrecte.
n13
30

nil est une valeur vide liée / correspondant à un objet (le type id en Objective-C). nil n'a pas de référence / adresse, juste une valeur vide.

NSString *str = nil;

Donc nil devrait être utilisé, si nous avons affaire à un objet.

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

Désormais, NULL est utilisé pour un pointeur non-objet (comme un pointeur C) dans Objective-C. Comme nul , NULL n'a aucune valeur ni adresse.

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

Donc, s'il y a une situation, lorsque je dois vérifier que ma structure (variable de type de structure) est vide ou non, j'utiliserai:

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

Prenons un autre exemple, le

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

De l' observation clé-valeur , le contexte doit être un pointeur C ou une référence d'objet. Ici, pour le contexte, nous ne pouvons pas utiliser nil ; nous devons utiliser NULL .

Enfin, la classe NSNull définit un objet singleton utilisé pour représenter des valeurs nulles dans des objets de collection (NSArray, NSDictionary). Le [NSNull null] sera renvoie l'instance de singleton de NSNull. Fondamentalement, [NSNull null] est un objet approprié.

Il n'existe aucun moyen d'insérer un objet nil dans un objet de type collection. Prenons un exemple:

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

Sur la deuxième ligne, nous n'obtiendrons aucune erreur, car il est parfaitement juste d'insérer un objet NSNull dans un objet de type collection. Sur la troisième ligne, nous obtiendrons l'erreur "l'objet ne peut pas être nul". Parce que nil n'est pas un objet.

Shad
la source
+1 pour mentionner l'utilisation pratique de nil / null dans un tableau.
Michael
19

NULL et nil sont égaux l'un à l'autre, mais nil est une valeur d'objet tandis que NULL est une valeur de pointeur générique ( (void*)0, pour être précis). [NSNull null]est un objet qui est censé remplacer nul dans les situations où nul n'est autorisé. Par exemple, vous ne pouvez pas avoir de valeur nil dans un NSArray. Donc, si vous devez représenter un «nul», vous pouvez utiliser [NSNull null].

Chuck
la source
12

J'ai trouvé ce qui suit:

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

De son apparence, il n'y a pas de différence mais une différence conceptuelle.

Colnaghi
la source
8

Méfiez-vous des if([NSNull null])retours true.

Nicolas Manzini
la source
7

Ils ne sont que des zéros typés. Fonctionnellement, il n'y a aucune différence entre eux. c'est à dire.,

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

Il y a une différence, mais seulement pour vous et les autres humains qui lisent le code, le compilateur s'en fiche.

Une autre chose nil est une valeur d'objet tandis que NULL est une valeur de pointeur générique.

Nirav
la source
6

Dans les SDK OS X et iOS modernes:

  • nilet Nilet NULLsont identiques en Objective-C et en Objective-C ++ avant C ++ 11.
  • nilet Nilet std::nullptrsont identiques en Objective-C ++ avec C ++ 11.

Stylistiquement, de nombreuses personnes préfèrent utiliser nil pour les objets Objective-C et / NULLou nullptrpour d'autres types de pointeurs. J'utilise moi-même maintenant nilpartout.

[NSNull null]est un objet singleton utilisé pour représenter des valeurs nulles dans des situations où il nilest interdit en tant que valeur (généralement dans un objet de collection tel qu'un NSArrayou NSDictionary). Rubriques de programmation de nombres et de valeurs: Utilisation de NSNull

Greg Parker
la source
5

Pour développer un commentaire de @cobbal:

MacTypes.h contient:

#ifndef nil
   #define nil NULL
#endif
Justin Tanner
la source
4

Comme déjà mentionné, ce sont les mêmes, mais j'utilise l'un ou l'autre selon la langue dans laquelle le framework correspondant a été écrit.

Pour tout ce qui concerne Objective-C, j'utilise nil. Par exemple:

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

    // process elements
    ...
}

Cependant, lors de la vérification de la validité des modèles de données à partir d'un framework C (comme le framework AddressBook et CoreFoundation), j'utilise NULL. Par exemple:

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

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

De cette façon, j'ai des indices subtils dans mon code si je traite avec du code basé sur Obj-C ou C.

Tafkadasoh
la source
4

nil est un pointeur d'objet vers rien. Bien que sémantiquement distincts de NULL , ils sont techniquement équivalents les uns aux autres.

Au niveau du framework, Foundation définit NSNull , qui définit une méthode de classe, + null, qui renvoie l'objet singleton NSNull. NSNull est différent de nil ou NULL , en ce sens qu'il s'agit d'un objet réel plutôt que d'une valeur nulle.

De plus, dans Foundation / NSObjCRuntime.h, Nil est défini comme un pointeur de classe vers rien.

Référez-vous ceci pour plus d'informations - nil / Nil / NULL / NSNull

Shubham Jain
la source
3

Il y a une différence dans certains contextes.

Littéralement, Null est un caractère: ASCII 0.

Nil équivaut à vide, aucune valeur.

Selon le contexte de programmation, cela peut être une grande différence.

Pain de viande
la source
1

Utilisez NULL par exemple lorsque vous appelez une méthode Objective-C avec un paramètre de sortie de type (NSError **).

Je vois beaucoup d'exemples de code sur le Web où les gens fournissent nil au lieu de NULL dans ce cas. C'est parce que c'est un pointeur vers un pointeur et donc pas directement un type d'objet Objective-C. Comme indiqué ci-dessus, nil doit être utilisé pour les types d'objets Objective-C.

Peter Mortensen
la source
1

Fondamentalement: nil: pointeur nul sur un objet et null: est pour un autre pointeur de type

gératchev
la source
0

nil signifie l'absence de valeur tandis que NULL représente No Object,

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

Ici [NSNULL null] est un objet qui signifie aucun objet, en même temps vous ne pouvez pas ajouter nil pour indiquer l'absence d'objet.

vous pouvez également utiliser nil et [NSNUll null] pour la vérification.

Roshan Sah
la source
0

Cela vous aidera à comprendre la différence entre nil, NIL et null.

Le lien ci-dessous peut vous aider d'une certaine manière:

http://nshipster.com/nil/

nil -> valeur nulle littérale pour les objets Objective-C.

Nil -> valeur nulle littérale pour les classes Objective-C.

NULL -> valeur nulle littérale pour les pointeurs C.

NSNULL -> objet singleton utilisé pour représenter null.

Subhakar Prabhu
la source
cela ajoute-t-il quelque chose de nouveau (qui n'est pas couvert par les réponses existantes)?
Florian Koch