NULL vs nil en Objective-C

182

Dans observeValueForKeyPath:ofObject:change:context:- pourquoi les documents utilisent-ils à la NULLplace de nillorsqu'ils ne spécifient pas de pointeur de contexte?

erikprice
la source
à mon avis, l'objet est nul, la classe est nulle et NULL en utilisant pour objet ou classe
Thanh Vũ Trần

Réponses:

227

nilne doit être utilisé qu'à la place d'un id, ce que nous, les programmeurs Java et C ++, considérerions comme un pointeur vers un objet. À utiliser NULLpour les pointeurs non-objet.

Regardez la déclaration de cette méthode:

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

Le contexte est un void *(c'est-à-dire un pointeur de style C), donc vous utiliseriez certainement NULL(qui est parfois déclaré comme (void *)0) plutôt que nil(qui est de type id).

Paul Tomblin
la source
2
Mais puisque le type de contextin observeValueForKeyPath:ofObject:change:context:est void *, cela ne signifie-t-il pas que les données passées en tant que contextpeuvent être un pointeur d'objet? Je pense que c'est un cas courant. C'est pourquoi je ne comprends pas pourquoi les documents utilisent toujours à la NULLplace de nil.
erikprice
2
Le type de contexte: dans cette méthode est "void *". "nil" n'est pas un "void *", mais NULL l'est.
Paul Tomblin
3
Vous pouvez. void * est n'importe quel pointeur. Néanmoins, vous avez absolument raison de dire que NULL est la constante correcte.
Peter Hosey
3
Ils ont dit nul *. NULL est pour void * et nil est pour id. Par conséquent, vous passez NULL. Si vous passez nul, vous mentez à votre lecteur qui pensera que cette méthode prend un identifiant.
Peter Hosey
12
Ou pour y penser autrement, NULL est un type plus large et nil est un sous-ensemble de NULL. En général, utilisez le type le plus large avec lequel vous pouvez vous en sortir (c'est-à-dire en Java, écrivez votre méthode pour attendre une collection au lieu d'un vecteur, sauf si vous avez besoin de quelque chose de spécifique de Vector)
Paul Tomblin
65

Ils sont techniquement la même chose (0), mais nil est généralement utilisé pour un type d'objet Objective-C, tandis que NULL est utilisé pour les pointeurs de style C (void *).

Marc Charbonneau
la source
8
En outre, NULLest défini différemment de nil. nilest défini comme (id)0. NULLn'est pas.
14
@WTP si vous lisez MacTypes.h, il déclare #define nil NULL
jbat100
1
C'est très intéressant. Il semble que cela n'a pas d'importance que pour les points de style. C'est comme OUI / VRAI et NON / FAUX.
Brennan
1
@Brennan, ce n'est pas tout à fait vrai, ce n'est pas parce que nil est défini comme NULL qu'il y a une autre implémentation cachée dans les coulisses. Par exemple, IBAction est défini comme nul mais il a une signification différente lors de l'utilisation du générateur d'interface lors de l'affichage de méthodes à attacher à des actions sur des boutons et autres.
Micaiah Wallace
53

Ils sont techniquement la même chose et ne diffèrent que par le style:

  • Le style Objective-C indique nilce qu'il faut utiliser pour le idtype (et les pointeurs vers des objets).
  • Le style C dit que NULLc'est ce que vous utilisez void *.
  • Le style C ++ indique généralement que vous devez simplement utiliser 0.

J'utilise généralement la variante qui correspond à la langue dans laquelle le type est déclaré .

Andrew
la source
14

NULLest le C equivalentde nil, un pointeur vers rien;

nil is zero typed as id,

NULL is zero typed as void*.

Un point important, vous ne pouvez pas envoyer de message à NULL. Il est donc préférable d'utiliser nil dans l'objectif-C à de nombreux endroits.


la source
4

Ils sont presque la même chose sauf,

nilest utilisé dans un style Objective-C. où NULLest pour les pointeurs de type C et est typé à (void *).

dan14941
la source
1
N'est-ce pas à peu près une répétition de cette réponse existante ?
Pang