How to detect if NSString is null?
Solution 1
The NULL
value for Objective-C objects (type id
) is nil
.
While NULL
is used for C pointers (type void *
).
(In the end both end up holding the same value (0x0
). They differ in type however.)
In Objective-C:
-
nil
(all lower-case) is a null pointer to an Objective-C object. -
Nil
(capitalized) is a null pointer to an Objective-C class. -
NULL
(all caps) is a null pointer to anything else (C pointers, that is). -
[NSNull null]
is a singleton for situations where use of nil is not possible (adding/receiving nil to/fromNSArray
s e.g.)
In Objective-C++:
- All of the above, plus:
-
null
(lowercase) ornullptr
(C++11 or later) is a null pointer to C++ objects.
So to check against nil
you should either compare against nil
(or NULL
respectively) explicitly:
if (getCaption == nil) ...
or let ObjC / C do it implicitly for you:
if (!getCaption) ...
This works as every expression in C (and with Objective-C being a superset thereof) has an implicit boolean value:
expression != 0x0 => true
expression == 0x0 => false
Now when checking for NSNull
this obviously wouldn't work as [NSNull null]
returns a pointer to a singleton instance of NSNull
, and not nil
, and therefore it is not equal to 0x0
.
So to check against NSNull
one can either use:
if ((NSNull *)getCaption == [NSNull null]) ...
or (preferred, see comments):
if ([getCaption isKindOfClass:[NSNull class]]) ...
Keep in mind that the latter (utilising a message call) will return false
if getCaption
happens to be nil
, which, while formally correct, might not be what you expect/want.
Hence if one (for whatever reason) needed to check against both nil
/NULL
and NSNull
, one would have to combine those two checks:
if (!getCaption || [getCaption isKindOfClass:[NSNull class]]) ...
For help on forming equivalent positive checks see De Morgan's laws and boolean negation.
Edit: NSHipster.com just published a great article on the subtle differences between nil, null, etc.
Solution 2
You should use
if ([myNSString isEqual:[NSNull null]])
This will check if object myNSString is equal to NSNull object.
Solution 3
Preferred Way to check for the NSNULL
is
if(!getCaption || [getCaption isKindOfClass:[NSNull class]])
Solution 4
if([getCaption class] == [NSNull class])
...
You can also do
if([getCaption isKindOfClass:[NSNull class]])
...
if you want to be future proof against new subclasses of NSNull.
Solution 5
Just check with this code:
NSString *object;
if(object == nil)
This should work.
iosfreak
Updated on July 08, 2022Comments
-
iosfreak almost 2 years
I have a piece of code that detects if a
NSString
isNULL
,nil
, etc. However, it crashes. Here is my code:NSArray *resultstwo = [database executeQuery:@"SELECT * FROM processes WHERE ready='yes' LIMIT 0,1"]; for (NSDictionary *rowtwo in resultstwo) { NSString *getCaption = [rowtwo valueForKey:@"caption"]; if (getCaption == NULL) { theCaption = @"Photo uploaded..."; } else if (getCaption == nil) { theCaption = @"Photo uploaded..."; } else if ([getCaption isEqualToString:@""]) { theCaption = @"Photo uploaded..."; } else if ([getCaption isEqualToString:@" "]) { theCaption = @"Photo uploaded..."; } }
And here's the error:
Terminating app due to uncaught exception '
NSInvalidArgumentException
', reason: '-[NSNull isEqualToString:]
: unrecognized selector sent to instance0x3eba63d4
'Am I doing something wrong? Do I need to do it a different way?
-
Admin about 13 yearsWhat’s the data type of
rowtwo
? Why are you sending it-valueForKey:
? -
Admin about 13 yearsI’ll leave this comment for further reference:
-valueForKey:
is a KVC method. In KVC,[NSNull null]
represents the absence of a value for a given key. If you’re using anNSDictionary
in a context that doesn’t need KVC, use-objectForKey:
instead — it will returnnil
instead of[NSNull null]
when a given key is not present in the dictionary. -
Admin about 13 yearsSee this Stack Overflow question for a discussion on the difference between
-valueForKey:
and-objectForKey:
: stackoverflow.com/questions/1062183/… -
iosfreak about 13 yearsGetting object from array populated by a database...
-
Admin about 13 years
rowtwo
is not an array, otherwise-valueForKey:
would return another array. Is it a dictionary? -
iosfreak about 13 yearsPlease see my edits in how I populated it and used a NSDictionary.
-
Admin about 13 yearsIt’s a dictionary, then. See my comments #2 and #3.
-
Admin about 13 yearsOne more note (ha! :-)) — it looks like you’re using some non-Apple class to fetch results from a database query. If a column is NULL (as in SQL NULL), this class has two options when populating a dictionary: either don’t include the corresponding key, or include the corresponding key mapping to an
[NSNull null]
value. So it is up to this class how to represent SQL NULL values, and your test needs to consider the specifics of this class. -
Mihir Oza almost 6 yearsYou can check my answer stackoverflow.com/a/51626469/3378413
-
-
Admin about 13 yearsTrue, although the actual error is that
[rowtwo valueForKey:@"caption"]
is returning anNSNull
instance instead of anNSString
instance. -
Regexident about 13 years@Bavarious: See last line in answer.
-
Caleb about 13 yearsSince NSNull is a singleton, you could actually compare pointers directly:
if (getCaption == [NSNull null])...
-
jscs about 13 years@phpnerd211: this probably doesn't solve your real problem, though -- see Bavarious's comments attached to the question.
-
iosfreak about 13 yearsHe was mistaken. I use this method all over my app and it functions properly -- see my edits in my code on how I populated the array, etc.
-
Admin about 13 years@phpnerd211 I advise you not to use
-valueForKey:
because it serves a different purpose. If you’re usingNSDictionary
, use its-[NSDictionary objectForKey:]
method. If you want to learn more about KVC and-valueForKey:
, there are a couple of guides on Apple’s web site. -
Dustin over 12 yearsgetCaption == [NSNull null] is a bad idea to use. It's better to do [getCaption class] == [NSNull class]. You're free to create new instances of NSNull and some JSON parsers do make new ones instead of using the singleton.
-
Dustin over 12 yearsBut comparing against the singleton is a bad idea! Don't do it =X. [NSNull null] may be a singleton but NSNull is a class like any other.
-
Patrick almost 12 yearsI found that using '(getCaption == [NSNull null])' worked fine but got a comparison warning so I changed it to 'if (getCaption == (id)[NSNull null])'
-
Evan R over 9 yearsOf all the answers on this page, only your top answer is working for me in Xcode 6.1, using an NSString property called
body
that's null. Debugger output:_body NSString * class name = NSNull 0x0000000107279ce0
andPrinting description of ad->_body: <null>
-
stackOverFlew almost 8 yearsI had to check for NSNull as well, strange. Seems my NSString was set
-
Bosoud over 5 yearsperfect answer , Clear
-
Genevios over 4 yearsBless you! Perfect answer!