9

I have a NSString object,

NSString *aString;

then are the two following versions equivalent?

Version 1 :

if ( (NSString *)[NSNull null] == aString )
{
   // Logic handling
}

Version 2 :

if ( nil == aString )
{
   // Logic handling
}

Reference Posts

  1. Difference among nil, Nil, and null

  2. How to detect if NSString is null?

  3. Apple's NSNull Class Reference

  4. How do I test if a string is empty in Objective C?

Update - Test Result

My simple test result shows that the above two versions have different behaviors:

  1. When aString is initialized and then assigned with nil:

    false for expression in version 1,

    true for expression in version 2.

  2. When aString is initialized with the value of @"".

    false for expression in version 1,

    false for expression in version 2.

So it's clear that the two versions are not equivalent in their behavior.

The test code:

NSString *aString = nil;
NSString *bString = [NSString stringWithFormat:@""];

if ((NSString *)[NSNull null] == aString) {
    NSLog(@"a1 - true");
} else {
    NSLog(@"a1 - false");
}

if (nil == aString) {
    NSLog(@"a2 - true");
} else {
    NSLog(@"a2 - false");
}

if ((NSString *)[NSNull null] == bString) {
    NSLog(@"b1 - true");
} else {
    NSLog(@"b1 - false");
}

if (nil == bString) {
    NSLog(@"b2 - true");
} else {
    NSLog(@"b2 - false");
}

Console output:

2013-10-31 00:56:48.132 emptyproject[31104:70b] a1 - false
2013-10-31 00:56:48.133 emptyproject[31104:70b] a2 - true
2013-10-31 00:56:48.133 emptyproject[31104:70b] b1 - false
2013-10-31 00:56:48.133 emptyproject[31104:70b] b2 - false

Update - What Do I Mean "Empty string"**

Now I've made it clearer that it's different for a NSString object to be nil and for it to be a valid initialized instance holding an empty string value of @"". What I really need in this post is that how to test if my NSString object is successfully initialized, that is, if aString is nil. I want to know if there is any difference for the above two versions of test code.

Community
  • 1
  • 1
George
  • 3,384
  • 5
  • 40
  • 64
  • How could they be equivalent? – Sulthan Oct 30 '13 at 08:40
  • To @Sulthan, so I can't replace `if ( aString == (NSString *)[NSNull null] )` with `if ( aString == nil )`? – George Oct 30 '13 at 08:42
  • No. What are you trying to do? – Sulthan Oct 30 '13 at 08:44
  • To @Sulthan, Trying to check an empty string, `@""`. – George Oct 30 '13 at 08:45
  • Also, you can replace `if ( aString == nil )` by `if (!aString)` – Jordan Montel Oct 30 '13 at 08:53
  • @congliu The best check for empty string is `aString.length == 0` – Sulthan Oct 30 '13 at 08:54
  • To @Sulthan, Does `[aString length]` also yields `0` even if `aString` fails to get initialized? For example, by this initialization code: `NSString *aString = [aNSMutableDictionaryVariable objectForKey:@"stringKey"];` and right after this initialization, there goes the check code `aString` with `if (0 == [aString length]){}` – George Oct 30 '13 at 09:54
  • To @JordanMontel, Do you mean `aString == nil` is wrong but `!aString` is correct? Or do you mean they're equivalent, but the latter is better since it's simpler? – George Oct 30 '13 at 09:56
  • 1
    it's equivalent but you tape less code :) – Jordan Montel Oct 30 '13 at 10:22
  • 1
    @congliu You should parse dictioaries smartly. Use a category on `NSDictionary` to convert `NSNull` to `nil` automatically. – Sulthan Oct 30 '13 at 10:22

6 Answers6

32

[NSNull null] and nil are not equivalent. [NSNull null] is meant to represent the concept of NULL (as in no object) in cases where nil cannot be used, for example in an NSArray (as you can only insert objects in them). [NSNull null] is an object (always the same object), while nil is a pointer to 0.

NSHipster has a nice discussion here. He says:

NSNull is used throughout Foundation and other frameworks to skirt around the limitations of collections like NSArray and NSDictionary not being able to contain nil values. You can think of NSNull as effectively boxing the NULL or nil value so that it can be used in collections.

If you have:

NSString *aString;
if ( aString == (NSString *)[NSNull null] )
{
   // Logic handling
}

then something's wrong, aString should point to an NSString object (or subclass), or nil. But not [NSNull null] which is an object of a different class, you shouldn't cast from one to the other.

EDIT:

Given in the comments you state that you wish to check if the string is empty (as in @""), that is different. See this question. An empty string is an NSString object, it is not nil and it is not [NSNull null].

Community
  • 1
  • 1
jbat100
  • 16,757
  • 4
  • 45
  • 70
  • To @jbat100, now I've made it clearer that it's different for a `NSString` object to be `nil` and for it to have `@""`. So what I really need in the post is that how to test if my `NSString` object is successfully initialized, that is, if `aString` is `nil`. – George Oct 30 '13 at 15:25
  • 1
    if (aString == nil) {//string is not initialized} – jbat100 Oct 30 '13 at 15:56
  • if (aString != nil) {//string is initialized} – jbat100 Oct 30 '13 at 15:56
  • 1
    "then something's wrong" The "something wrong" could be laziness. Sometimes people put an object of uncertain class in the variable and check it later, to save having to introduce another variable. – newacct Oct 31 '13 at 02:02
  • Maybe `string.length > 0` ? – Nike Kov Sep 08 '16 at 11:33
6

they are not the same, the NSNull is a valid object (inherited from NSObject) opposite a nil pointer, which points to nothing.

that is how you can check, whether an object is an NSNull object, but you first version is also okay.

id _object = // any kind of NSObject ...

if ([_object isKindOfClass:[NSNull class]]) {
   // Logic handling
}
holex
  • 23,961
  • 7
  • 62
  • 76
0

nil means nothing.
[NSNull null] is an object, instance of class NSNull
== means equality

something equals to something else is not the same as something is equal to nothing

Sulthan
  • 128,090
  • 22
  • 218
  • 270
0

[NSNull null] returns the singleton instance of NSNull.

aString == [NSNull null] compares two pointers. As long as aString does not point to the NSNull singleton, they will never be equal.

Sebastian
  • 7,670
  • 5
  • 38
  • 50
0

If you want to match a string to nil:
1. if(aString.length==0) { }
2.if(sString isEqualToString:@"") { }
3.if(aString!=nil) { } else { //do your stuff here }

Muruganandham K
  • 5,271
  • 5
  • 34
  • 62
0
+(NSString*)replaceNullValuesWithEmptyString:(id)tempObj
{
if (([tempObj isKindOfClass:[NSNull class]])||
    (tempObj == nil) ||
    (tempObj == (id)[NSNull null])||
    [tempObj isEqual:[NSNull null]] ||
    [tempObj isEqual:nil]) {
}
else {
    if([tempObj respondsToSelector:@selector(isEqualToString:)]) {
        if ([tempObj isEqualToString:@"<null>"] ||
            [tempObj isEqualToString:@"(null)"]) {
        }
        else {
            if ([tempObj respondsToSelector:@selector(length)]) {
                if ([tempObj length]>0) {
                     NSLog(@"Check Passed.");
                    return tempObj;
                }
            }
        }
    }
}
NSLog(@"Check failed.");
return @"";

}

Mannam Brahmam
  • 2,225
  • 2
  • 24
  • 36