Wann sollte ich in Objective-C nil und NULL verwenden?

170

Dies ist ein Beispielcode:

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

Wann sollte ich nil, NULL und [NSNull null] verwenden?

Biranchi
quelle
4
Es hängt mit der Frage nach Ziel C zusammen.
Biranchi
nilbedeutet eine Art NULLfür objc Instanz. Sie können also einen bestimmten Wert markieren, der für eine Objektinstanz oder einen generischen Zeiger vorgesehen ist. Im Hinblick auf Typmanagement und Sicherheit wird Ihnen dies sehr helfen.
Eonil
4
nilund null/ NULLsind gleich - beide als Null definiert. Als Formalität nilbeim Codieren von Objective-C und NULLbeim Codieren regulärer C / C ++ - Anweisungen / Aufrufe verwenden. NSNullist jedoch etwas ganz anderes. Es ist ein Singleton-Objekt, das als Platzhalter dient, um "nichts" in z. B. NSDictionarys darzustellen, in denen Null- / Null-Zeiger nicht zulässig sind.
Hot Licks
Siehe Link für eine gute Erklärung [hier] [1] [1]: stackoverflow.com/questions/5908936/…
Ameer
1
mögliches Duplikat von NULL vs nil in Objective-C
awiebe

Antworten:

114

Sie können nilungefähr überall verwenden, wo Sie verwenden können null. Der Hauptunterschied besteht darin, dass Sie Nachrichten an senden können nil, sodass Sie sie an einigen Stellen verwenden können, an denen sie nullnicht funktionieren können.

Im Allgemeinen nur verwenden nil.

Alex
quelle
12
Technisch gesehen sind sie genau gleich. Sie können Nachrichten sowohl an nil als auch an NULL senden. Idiomatisch, obwohl Null normalerweise verwendet wird, um ein Objekt
darzustellen
41
auch in MacTypes.h gibt es#define nil NULL
Cobbal
8
Ja, wie Cobbal sagt, sind sie gleich. Es ist eher eine Kontextreferenz, bei der NULL ein Zeiger auf 0x0 ist, nil ein nicht existierendes Ziel-c-Objekt ist und Nil eine nicht existierende Ziel-c-Klasse ist, aber technisch gesehen sind sie alle nur 0. Außerdem ist es NULL nicht null - null ist in Java oder C #, aber nicht in Objective-C.
Jason Coco
16
Diese akzeptierte Antwort erkennt nicht an, dass [NSNull null]es sich um ein ganz anderes Tier handelt. Um aus der NSNull-Klassenreferenz zu zitieren : "Die NSNull-Klasse definiert ein Singleton-Objekt, das zur Darstellung von Nullwerten in Sammlungsobjekten verwendet wird (die keine Nullwerte zulassen)." Siehe auch NSNull Verwendung Abschnitt Anzahl und Wert der Programmierung.
Rob
"Der Hauptunterschied besteht darin, dass Sie Nachrichten an nil senden können" - Sie können auch Nachrichten an senden NULL.
313

Sie unterscheiden sich in ihren Typen. Sie sind alle Null, aber sie NULLsind ein void *, nilein idund Nilein Klassenzeiger.

NSResponder
quelle
14
Beste Erklärung, die ich von dem Unterschied gehört habe (: Danke.
Jacob
3
Dies sollte die akzeptierte Antwort sein, nicht weil es mehr Up-Votes gibt, sondern weil es die beste Erklärung für die gestellte Frage gibt.
James Mertz
5
Elegante Beschreibung von NULLv nil, aber dies verfehlt ernsthaft die Marke re [NSNull null]. Siehe Verwenden von NSNull Abschnitt Anzahl und Wert der Programmierung und NSNull Klassenreferenz .
Rob
Beide scheinen Hinweise zu sein void *. Eine andere Antwort hier erwähnt dies bereits, aber wenn Sie sich damit beschäftigen objc.h, finden Sie die Zeile #define nill __DARWIN_NULL.
gkb0986
1
Diese Antwort klingt gut, ist aber nach den anderen Antworten einfach falsch.
n13
30

nil ist ein leerer Wert, der an ein Objekt gebunden ist / diesem entspricht (der ID-Typ in Objective-C). nil hat keine Referenz / Adresse, nur einen leeren Wert.

NSString *str = nil;

Es sollte also Null verwendet werden, wenn es sich um ein Objekt handelt.

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

Jetzt wird NULL für Nicht-Objekt-Zeiger (wie ein C-Zeiger) in Objective-C verwendet. Wie Null hat NULL weder einen Wert noch eine Adresse.

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

Wenn es also eine Situation gibt, in der ich überprüfen muss, ob meine Struktur (Strukturtypvariable) leer ist oder nicht, verwende ich:

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

Lassen Sie uns ein anderes Beispiel haben, das

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

Bei der Beobachtung von Schlüsselwerten sollte der Kontext ein C-Zeiger oder eine Objektreferenz sein. Hier können wir für den Kontext nicht Null verwenden ; wir müssen NULL verwenden .

Schließlich definiert die NSNull- Klasse ein Singleton-Objekt, das zur Darstellung von Nullwerten in Auflistungsobjekten (NSArray, NSDictionary) verwendet wird. Die [NSNull null] gibt die Singleton-Instanz von NSNull zurück. Grundsätzlich ist [NSNull null] ein richtiges Objekt.

Es gibt keine Möglichkeit, ein Nullobjekt in ein Objekt vom Typ Sammlung einzufügen. Lassen Sie uns ein Beispiel haben:

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

In der zweiten Zeile wird kein Fehler angezeigt, da es durchaus fair ist, ein NSNull-Objekt in ein Objekt vom Typ Sammlung einzufügen. In der dritten Zeile erhalten wir den Fehler "Objekt kann nicht Null sein". Weil Null kein Objekt ist.

Shad
quelle
+1 für die Erwähnung der praktischen Verwendung von nil / null im Array.
Michael
19

NULL und nil sind gleich, aber nil ist ein Objektwert, während NULL ein generischer Zeigerwert ist ( (void*)0um genau zu sein). [NSNull null]ist ein Objekt, das in Situationen, in denen Null nicht erlaubt ist, für Null stehen soll. Beispielsweise können Sie in einem NSArray keinen Nullwert haben. Wenn Sie also ein "Null" darstellen müssen, können Sie verwenden [NSNull null].

Chuck
quelle
12

Ich habe folgendes gefunden:

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

So wie es aussieht, gibt es keinen Unterschied außer einem konzeptionellen.

Colnaghi
quelle
8

Passen Sie auf, dass if([NSNull null])zurückkehrt true.

Nicolas Manzini
quelle
7

Sie sind beide nur typisierte Nullen. Funktionell gibt es keinen Unterschied zwischen ihnen. dh.,

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

Es gibt einen Unterschied, aber nur für Sie und andere Menschen, die den Code lesen, ist es dem Compiler egal.

Eine weitere Sache ist, dass nil ein Objektwert ist, während NULL ein generischer Zeigerwert ist.

Nirav
quelle
6

In modernen OS X- und iOS-SDKs:

  • nilund Nilund NULLsind in Objective-C und in Objective-C ++ vor C ++ 11 identisch.
  • nilund Nilund std::nullptrsind in Objective-C ++ mit C ++ 11 identisch.

Stilistisch bevorzugen viele Menschen die Verwendung nilfür Objective-C-Objekte und / NULLoder nullptrfür andere Zeigertypen. Ich selbst benutze jetzt nilüberall.

[NSNull null]ist ein Singleton- Objekt, das zur Darstellung von Nullwerten in Situationen verwendet wird, in denen nildies als Wert verboten ist (normalerweise in einem Sammlungsobjekt wie einem NSArrayoder NSDictionary). Themen zur Zahlen- und Wertprogrammierung: Verwenden von NSNull

Greg Parker
quelle
5

So erweitern Sie einen Kommentar von @cobbal:

MacTypes.h enthält:

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

Wie bereits erwähnt, sind sie gleich, aber ich verwende entweder das eine oder das andere, abhängig von der Sprache, in der das entsprechende Framework geschrieben wurde.

Für alles, was mit Objective-C zu tun hat, verwende ich nil. Beispielsweise:

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

    // process elements
    ...
}

Wenn ich jedoch die Gültigkeit von Datenmodellen aus einem C-Framework (wie AddressBook Framework und CoreFoundation) überprüfe, verwende ich NULL. Beispielsweise:

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

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

Auf diese Weise habe ich subtile Hinweise in meinem Code, wenn es sich um Obj-C- oder C-basierten Code handelt.

Tafkadasoh
quelle
4

nil ist ein Objektzeiger auf nichts. Obwohl sie sich semantisch von NULL unterscheiden , sind sie technisch äquivalent zueinander.

Auf Framework-Ebene definiert Foundation NSNull , das eine Klassenmethode definiert, + null, die das Singleton-NSNull-Objekt zurückgibt. NSNull unterscheidet sich von nil oder NULL darin , dass es sich eher um ein tatsächliches Objekt als um einen Nullwert handelt.

Zusätzlich wird in Stiftung / NSObjCRuntime.h, Nil ist definiert als eine Klasse Zeiger auf nichts.

Weitere Informationen finden Sie hier - nil / Nil / NULL / NSNull

Shubham Jain
quelle
3

In einigen Kontexten gibt es einen Unterschied.

Null ist buchstäblich ein Zeichen: ASCII 0.

Null ist gleich leer, kein Wert.

Je nach Programmierkontext kann dies ein großer Unterschied sein.

Hackbraten
quelle
1

Verwenden Sie NULL beispielsweise, wenn Sie eine Objective-C-Methode mit einem Ausgabeparameter vom Typ (NSError **) aufrufen.

Ich sehe viele Beispielcodes im Web, in denen in diesem Fall Null anstelle von NULL angegeben wird. Dies liegt daran, dass es sich um einen Zeiger auf einen Zeiger handelt und somit nicht direkt um einen Objective-C-Objekttyp. Wie oben erwähnt, sollte für Objective-C-Objekttypen nil verwendet werden.

Peter Mortensen
quelle
1

Grundsätzlich gilt: nil: Nullzeiger auf ein Objekt und null: steht für einen anderen Zeigertyp

gerachev
quelle
0

nil bedeutet das Fehlen eines Wertes, während NULL No Object darstellt.

NSArray * array = @ [@ "Hallo Welt!", @ 101, [NSNULL null]];

Hier ist [NSNULL null] ein Objekt, das kein Objekt bedeutet. Gleichzeitig können Sie kein Null hinzufügen, um das Fehlen eines Objekts anzuzeigen.

Sie können sowohl nil als auch [NSNUll null] zur Überprüfung verwenden.

Roshan Sah
quelle
0

Dies wird Ihnen helfen, den Unterschied zwischen null, null und null zu verstehen.

Der folgende Link kann Ihnen in gewisser Weise helfen:

http://nshipster.com/nil/

nil -> Literal-Nullwert für Objective-C-Objekte.

Null -> Literal-Nullwert für Objective-C-Klassen.

NULL -> Literal-Nullwert für C-Zeiger.

NSNULL -> Singleton-Objekt zur Darstellung von Null.

Subhakar Prabhu
quelle
Fügt dies etwas Neues hinzu (was in den vorhandenen Antworten nicht abgedeckt ist)?
Florian Koch