まあ、私はそれは非常に工夫された例を使って説明できると思います。ArrayList内のすべての要素を出力するJavaのメソッドがあるとします。
void foo(ArrayList list)
{
for(int i = 0; i < list.size(); ++i){
System.out.println(list.get(i).toString());
}
}
次に、そのメソッドを次のように呼び出すと、someObject.foo(NULL); リストにアクセスしようとすると、おそらくNullPointerExceptionが発生します。この場合は、list.size()の呼び出しです。さて、おそらくそのようなNULL値でsomeObject.foo(NULL)を呼び出すことはないでしょう。ただし、someObject.foo(otherObject.getArrayList());のようなArrayListを生成するエラーが発生した場合にNULLを返すメソッドからArrayListを取得した可能性があります。
もちろん、次のようなことをした場合にも問題が発生します。
ArrayList list = NULL;
list.size();
これで、Objective-Cには同等のメソッドがあります。
- (void)foo:(NSArray*)anArray
{
int i;
for(i = 0; i < [anArray count]; ++i){
NSLog(@"%@", [[anArray objectAtIndex:i] stringValue];
}
}
ここで、次のコードがあるとします。
[someObject foo:nil];
JavaがNullPointerExceptionを生成する同じ状況があります。nilオブジェクトは最初に[anArray count]でアクセスされますが、NullPointerExceptionをスローする代わりに、Objective-Cは上記のルールに従って単に0を返すため、ループは実行されません。ただし、ループを設定された回数実行するように設定すると、最初に[anArray objectAtIndex:i]のanArrayにメッセージが送信されます。これも0を返しますが、objectAtIndex:はポインターを返し、0へのポインターはnil / NULLであるため、ループを介して毎回NSLogにnilが渡されます。(NSLogは関数でありメソッドではありませんが、nil NSStringが渡されると(null)を出力します。
場合によっては、NullPointerExceptionを設定した方がよい場合があります。これは、プログラムに問題があることをすぐに確認できるためです。ただし、例外をキャッチしないと、プログラムはクラッシュします。(Cでは、この方法でNULLを逆参照しようとすると、プログラムがクラッシュします。)Objective-Cでは、代わりに実行時の動作が正しくない可能性があります。ただし、0 / nil / NULL /ゼロ化された構造体を返しても壊れないメソッドがある場合、これにより、オブジェクトまたはパラメーターがnilであることを確認する必要がなくなります。