Objective-CでnilとNULLを使用する必要があるのはいつですか?


170

これはサンプルコードです:

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

いつnil、NULL、[NSNull null]を使用すればよいですか?


4
これは、Objective Cの質問に関連しています。
Biranchi、2009年

nilは一種のNULLobjcインスタンスを意味します。そのため、特定の値をobjcインスタンスまたはジェネリックポインター用にマークすることができます。型管理と安全性の観点から、これはあなたを大いに助けます。
eonil

4
nilnull/ NULLは同じです。どちらもゼロとして定義されています。形式として、nilObjective-Cをコーディングするとき、およびNULL通常のC / C ++ステートメント/呼び出しをコーディングするときに使用します。 NSNullただし、まったく異なるものです。これは、nil / nullポインタが許可されていないNSDictionarysなどで「何もない」を表すプレースホルダとして機能するシングルトンオブジェクトです。
ホットリックス

:[ここ]良い説明[1] [1]のリンクを参照してくださいstackoverflow.com/questions/5908936/...
アミール

回答:


114

あなたは使用することができnil、使用することができますどこでもについてnull。主な違いは、にメッセージを送信nilできるため、機能しない場所で使用できることnullです。

通常はを使用しますnil


12
技術的には、これらはまったく同じであり、nilとNULLの両方にメッセージを送信できます。慣用的に、通常nilはオブジェクトを表すために使用されます
cobbal

41
また、MacTypes.hにもあります#define nil NULL
cobbal

8
ええ、コッバルが言うように、彼らは同じです。NULLは0x0へのポインタであり、nilは存在しないobjective-cオブジェクトであり、Nilは存在しないobjective-cクラスですが、技術的にはすべて0です。また、NULLではありません。 null-nullはJavaまたはC#にありますが、Objective-Cにはありません。
Jason Coco

16
この受け入れられた答え[NSNull null]は、それが非常に異なる獣であることを認めることができません。NSNullクラスリファレンスから引用すると、「NSNullクラスは、コレクションオブジェクト(nil値を許可しない)でnull値を表すために使用されるシングルトンオブジェクトを定義します。」「数値と値のプログラミングトピック」の「NSNullの使用」セクションも参照してください
Rob

「主な違いは、メッセージをnilに送信できることです」-メッセージも送信できますNULL

313

それらはタイプが異なります。彼らはすべてゼロだが、NULLvoid *nilされid、そしてNilクラスのポインタです。


14
最良の説明違いを聞いたことがあります(:ありがとう。
ジェイコブ

3
賛成票が多いからではなく、提起された質問に対する最良の説明があるため、これは受け入れられる答えになるはずです。
James Mertz、2012年

5
NULLvのエレガントな説明ですnilが、これはreのマークを大幅に外してい[NSNull null]ます。「数値と値のプログラミングトピック」の「NSNullの使用」セクションおよび「NSNullクラスリファレンス」を参照してください
Rob

どちらもへのポインタのようvoid *です。ここでの別の答えはすでにこれについて言及していますが、を掘り下げるとobjc.h、行が見つかります#define nill __DARWIN_NULL
gkb0986 2013年

1
この答えは良さそうに聞こえますが、他の答えによると、それは単に間違っています。
n13 2014年

30

nilは、オブジェクト(Objective-Cのidタイプ)にバインド/対応する空の値です。nilは参照/アドレスを取得せず、空の値を取得しました。

NSString *str = nil;

したがって、オブジェクトを扱う場合は、nilを使用する必要があります。

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

NULLをするために使用される非オブジェクト・ポインタのObjective-Cで(Cポインタなど)。nilと同様に、NULLには値もアドレスもありませんでした。

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

したがって、状況がある場合、構造体(構造型変数)が空かどうかを確認する必要がある場合は、次を使用します。

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

別の例を見てみましょう、

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

キーと値の観察、コンテキストは、Cポインタまたはオブジェクト参照であるべきです。ここでは、コンテキストではnilを使用できません。NULLを使用する必要があります

最後に、NSNullクラスは、コレクションオブジェクト(NSArray、NSDictionary)でnull値を表すために使用されるシングルトンオブジェクトを定義します。【nsnullをヌル]意志戻りnsnullをのシングルトンインスタンス。基本的に[NSNull null]は適切なオブジェクトです。

コレクション型オブジェクトにnilオブジェクトを挿入する方法はありません。例を挙げましょう:

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

2行目では、NSNullオブジェクトをコレクション型オブジェクトに挿入することが完全に公正であるため、エラーは発生しません。3行目では、「object cannot be nil」エラーが発生します。nilはオブジェクトではないからです。


+1は、配列内でのnil / nullの実用的な使用について言及しています。
Michael

19

NULLとnilは互いに等しいが、nilはオブジェクト値であり、NULLは一般的なポインタ値((void*)0具体的には)である。[NSNull null]nilが許可されていない状況でnilの代わりになることを意図したオブジェクトです。たとえば、NSArrayにnil値を含めることはできません。したがって、「nil」を表す必要がある場合は、を使用できます[NSNull null]


12

私は以下を見つけました:

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

見た目は違いありませんが、概念的なものです。



7

どちらもゼロの型キャストです。機能的には、それらの間に違いはありません。つまり、

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

違いはありますが、コードを読むのはあなた自身と他の人間だけであり、コンパイラは気にしません。

もう1つ、nilはオブジェクト値ですが、NULLは汎用ポインタ値です。


6

最新のOS XおよびiOS SDKの場合:

  • nilNilNULLのObjective-CおよびC ++ 11前のObjective-C ++で同一です。
  • nilNilstd::nullptrC ++ 11とのObjective-C ++で同一です。

文体、多くの人が使用することを好むnilのObjective-Cのオブジェクトに対しておよびNULLまたはnullptr他のポインタ型のため。私は今nilどこでも使用しています。

[NSNull null]が値として禁止されている状況(通常、または などのコレクションオブジェクト)でnull値を表すために使用するシングルトンオブジェクトです。数値と値のプログラミングトピック:NSNullの使用nilNSArrayNSDictionary



4

すでに述べたように、それらは同じですが、対応するフレームワークが書かれた言語に応じて、どちらか一方を使用します。

Objective-Cに関連するすべてのものには、nilを使用します。例えば:

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

    // process elements
    ...
}

ただし、Cフレームワーク(AddressBookフレームワークやCoreFoundationなど)からデータモデルの有効性をチェックする場合は、NULLを使用します。例えば:

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

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

このように、Obj-CまたはCベースのコードを扱っている場合、コードに微妙な手掛かりがあります。


4

nilは何もへのオブジェクトポインタではありません。意味的にNULLとは異なりますが、技術的には同等です。

フレームワークレベルで、Foundationはクラスメソッドを定義するNSNullを定義します。+ nullはシングルトンNSNullオブジェクトを返します。NSNullは、ゼロ値ではなく実際のオブジェクトであるという点で、nilまたはNULLとは異なります。

さらに、Foundation / NSObjCRuntime.hでは、Nilは何もへのクラス ポインターとして定義されていません。

詳細については、これを参照してください-nil / Nil / NULL / NSNull


3

状況によって違いがあります。

文字通り、ヌルは文字です:ASCII 0。

Nilは空白と同等で、値はありません。

プログラミングコンテキストによっては、これは大きな違いになる可能性があります。


1

たとえば、タイプ(NSError **)の出力パラメーターを使用してObjective-Cメソッドを呼び出す場合は、NULLを使用します。

この場合、人々はNULLの代わりにnilを提供する多くのサンプルコードをWeb上で見ます。これは、ポインターへのポインターであり、直接Objective-Cオブジェクトタイプではないためです。上記のように、Objective-Cオブジェクトタイプにはnilを使用する必要があります。



0

nilは値がないことを意味し、NULLはオブジェクトなしを表します。

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

ここで[NSNULL null]はオブジェクトがないことを意味するオブジェクトであると同時に、オブジェクトが存在しないことを示すためにnilを追加することはできません。

チェックにもnilと[NSNUll null]の両方を使用できます。


0

これは、nil、NIL、nullの違いを理解するのに役立ちます。

以下のリンクは、いくつかの方法であなたを助けるかもしれません:

http://nshipster.com/nil/

nil-> Objective-Cオブジェクトのリテラルnull値。

Nil-> Objective-Cクラスのリテラルnull値。

NULL-> Cポインターのリテラルnull値。

NSNULL-> nullを表すために使用されるシングルトンオブジェクト。


これは何か新しいものを追加しますか(既存の回答ではカバーされていません)?
Florian Koch
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.