La valeur nulle est également une valeur spéciale. En programmation quotidienne, c'est évidemment indispensable, mais l'utilisez-vous bien ?
Sans plus tarder, commençons par la conclusion :
- nil : généralement utilisé pour représenter un pointeur nul d'un objet d'instance, tel que id obj = nil ;
- Nil : généralement utilisé pour représenter un pointeur nul d'un objet de classe, tel que Class cls = Nil;
- NULL : généralement utilisé pour représenter un pointeur nul vers un type non objet (type de données de base, type C), tel que char *c = NULL ;
- NSNull : généralement utilisé dans les objets de collection pour représenter des valeurs nulles, telles que NSArray * arr = @[[NSNull null]] ;
Alors, d'où vient la conclusion ci-dessus? Autoritairement, nous devons encore commencer par la source officielle, comme le code source officiel. téléchargement direct
néant
Dans le code source on retrouve directement nil
la définition de :
#ifndef nil
# if __has_feature(cxx_nullptr)
# define nil nullptr
# else
# define nil __DARWIN_NULL
# endif
#endif
复制代码
nil
Le scénario d'utilisation du code source de recherche globale concerne principalement le pointeur nul de l'objet d'instance mentionné ci-dessus.
Néant
De même, on peut aussi trouver sa définition dans le code source :
#ifndef Nil
# if __has_feature(cxx_nullptr)
# define Nil nullptr
# else
# define Nil __DARWIN_NULL
# endif
#endif
复制代码
L'AS-tu trouvé? Exactement la même que lanil
définition de ! Nil
Pourquoi?
Aucune raison, les deux sont des pointeurs nuls, dont la valeur est totalement cohérente, mais nous pouvons constater à partir des scénarios d'utilisation du code source, des commentaires de code, etc., qu'ils Nil
sont principalement utilisés pour les pointeurs nuls d'objets de classe, ce qui semble être la convention officielle du code source. Oui, pourquoi ne devrions-nous pas la suivre ?
NUL
En parlant NULL
de, à partir du code source ( stddef.h
), les définitions sont légèrement différentes :
#undef NULL
#ifdef __cplusplus
#if __cplusplus >= 201103L
#define NULL nullptr
#else
#undef __null // VC++ hack.
#define NULL __null
#endif
#else
#define NULL ((void*)0)
#endif
复制代码
L'avant de la définition est principalement de juger si c'est C++
, et OC
ce n'est évidemment pas , donc ça va toujours #define NULL ((void*)0)
. Est-ce sous la forme de pointeurs vers les types de données de base que nous connaissons ?
Combiné avec les scénarios d'utilisation de son code source, il est NULL
principalement utilisé pour les pointeurs nuls de types non-objet.
un bref résumé
En fait, on remarque que dans nil
la Nil
définition de , est __DARWIN_NULL
en fait NULL
:
#ifndef __DARWIN_NULL
#define __DARWIN_NULL NULL
#endif
复制代码
Au lieu de cela, __has_feature(cxx_nullptr)
est utilisé pour déterminer si C++11
une nullptr
fonctionnalité est prise en charge.
nullptr
C++
est le type de valeur nulle du pointeur dans .
Est-ce que tout est clair ici ?
Jusqu'à présent, en fait, nous pouvons voir que les valeurs de nil
, Nil
, et NULL
ces trois sont cohérentes dans certains scénarios, c'est-à-dire que dans ces scénarios, elles peuvent être mélangées, en particulier nil
avec Nil
, mais dans notre développement habituel, c'est Mieux vaut ne pas le faire. D'une part, il s'agit d'une convention officielle, et d'autre part, il peut y avoir des problèmes causés par des incohérences.
Maintenant, il existe une règle simple et claire, et il n'y a aucun risque d'erreur, alors pourquoi ne pas le faire ?
NSNull
Au final, il nous reste encore ce qu'il reste NSNull
, pourquoi en parle-t-on à part ? Car ce n'est pas du tout la même chose que la précédente.
NSNull
NSObject
est une sous-classe de :
@interface NSNull : NSObject <NSCopying, NSSecureCoding>
+ (NSNull *)null;
@end
复制代码
Le fichier d'en-tête montre qu'il a une méthode de classe, qui est en fait une méthode pour obtenir son singleton.
Ses scénarios d'utilisation sont principalement dans certains objets de collection, comme suit :
// 数组中使用
NSArray *array = [NSArray arrayWithObjects:
[[NSObject alloc] init],
[NSNull null],
@"aaa",
nil,
[[NSObject alloc] init],
[[NSObject alloc] init], nil];
NSLog(@"%ld", array.count); // 输出 3,NSArray以nil结尾
// 字典中使用
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
@"Object0", @"Key0",
@"Object1", @"Key1",
nil, @"Key-nil"
@"Object2", @"Key2",
nil];
NSLog(@"%@", dictionary); // 输出2个key-value,NSDictionary也是以nil结尾
// 可变字典中使用
NSMutableDictionary *mutableDictionary = [[NSMutableDictionary alloc] init];
[mutableDictionary setObject:nil forKey:@"Key-nil"]; // 会引起Crash
[mutableDictionary setObject:[NSNull null] forKey:@"Key-nil"]; // 不会引起Crash
//所以在使用时,如下方法是比较安全的
[mutableDictionary setObject:(nil == value ? [NSNull null] : value)
forKey:@"Key"];
复制代码
Oh, nous y sommes, comprenez-vous l'utilisation de diverses valeurs nulles ? J'espère gagner quelque chose.