Objective-c nil,Nil,NULLとNSNullの違い


OCではnil,Nil,NULL,NSNullによく遭遇する可能性がありますが、以下の違いを分析します.
Symbol
Value
Meaning
NULL
(void *)0
literal null value for C pointers
nil
(id)0
literal null value for Objective-C objects
Nil
(Class)0
literal null value for Objective-C classes
NSNull
[NSNull null]
singleton object used to represent null
一、nil:オブジェクトが空
インスタンスオブジェクトをNull値として定義します.例:
NSObject* obj = nil;
        if (nil == obj) {
            NSLog(@"obj is nil");
        }
        else {
            NSLog(@"obj is not nil");
        }

二、Nil:クラスが空
クラスを空に定義します.例:
Class someClass = Nil;
        Class anotherClass = [NSString class];

三、NULL:基本データオブジェクトポインタが空
c言語で使用される様々なデータ型のポインタは空です.例:
int *pointerToInt = NULL; 
char *pointerToChar = NULL; 
struct TreeNode *rootNode = NULL;

四、NSNull
コレクションオブジェクトには、NSArray、NSSet、NSDictionaryなどのnilを特定の値として含めることはできません.したがって、nil値は、特定のオブジェクトNSNullで表される.NSNullは、オブジェクト属性のnil値を表す単一のインスタンスを提供します.
@interface NSNull : NSObject <NSCopying, NSSecureCoding>

+ (NSNull *)null;

@end

NSNullの一例クラスにおいて、唯一の方法null:Returns the singleton instance of NSNullが提供される.
例:
 NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
        mutableDictionary[@"someKey"] = [NSNull null]; // Sets value of NSNull singleton for `someKey`
        NSLog(@"Keys: %@", [mutableDictionary allKeys]); // @[@"someKey"]

五、説明:
Technically they're all the same, but in practice they give someone reading your code some hints about what's going on; just like naming classes with a capital letter and instances with lowercase is recommended, but not required. If someone sees you passing NULL, they know the receiver expects a C pointer. If they see nil, they know the receiver is expecting an object. If they see Nil, they know the receiver is expecting a class. Readability.
六、注
興味深い例をいくつか添付します.
(1)
NSObject *obj1 = [[NSObject alloc] init];
        NSObject *obj2 = [NSNull null];
        NSObject *obj3 = [NSObject new];
        NSObject *obj4;
        NSArray *arr1 = [NSArray arrayWithObjects:obj1, obj2, obj3, obj4, nil];
        NSLog(@"arr1 count: %ld", [arr1 count]);    //arr1 count: 3


        NSObject *obj1;
        NSObject *obj2 = [[NSObject alloc] init];
        NSObject *obj3 = [NSNull null];
        NSObject *obj4 = [NSObject new];
        NSArray *arr2 = [NSArray arrayWithObjects:obj1, obj2, obj3, obj4, nil];
        NSLog(@"arr2 count: %ld", [arr2 count]);   //arr2 count: 0

なぜ最初の配列要素は3つあり、2番目の配列要素は0であるのか.まず、
NSObject* obj;
        if (nil == obj) {
            NSLog(@"obj is nil");
        }
        else {
            NSLog(@"obj is not nil");
        }
この出力:obj is nil.NSArrayはnilで終わる.だから原因がわかったんだろう!
(2)
// !
        NSObject *obj1 = [NSNull null];
        NSArray *arr1 = [NSArray arrayWithObjects:@"One", @"TWO", obj1, @"three" ,nil];
        for (NSString *str in arr1) {
            NSLog(@"array object: %@", [str lowercaseString]);
        }

        // 
        NSObject *obj1 = [NSNull null];
        NSArray *arr1 = [NSArray arrayWithObjects:@"One", @"TWO", obj1, @"three" ,nil];
        for (NSString *str in arr1) {
            if (![str isEqual:[NSNull null]]){
                NSLog(@"array object: %@", [str lowercaseString]);
            }
        }