Les valeurs nulles en OC (nil, Nil, NULL, NSNull), l'utilisez-vous bien ?

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 nilla définition de :

#ifndef nil
# if __has_feature(cxx_nullptr)
#   define nil nullptr
# else
#   define nil __DARWIN_NULL
# endif
#endif
复制代码

nilLe 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 ! NilPourquoi?

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 Nilsont 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 NULLde, à 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 OCce 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 NULLprincipalement utilisé pour les pointeurs nuls de types non-objet.

un bref résumé

En fait, on remarque que dans nilla Nildéfinition de , est __DARWIN_NULLen 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++11une nullptrfonctionnalité est prise en charge.

nullptrC++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 NULLces trois sont cohérentes dans certains scénarios, c'est-à-dire que dans ces scénarios, elles peuvent être mélangées, en particulier nilavec 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.

NSNullNSObjectest 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.

Je suppose que tu aimes

Origine juejin.im/post/7078624442816921637
conseillé
Classement