I have a piece of code that detects if a NSString
is NULL
, 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?
You can also do
if you want to be future proof against new subclasses of NSNull.
The
NULL
value for Objective-C objects (typeid
) isnil
.While
NULL
is used for C pointers (typevoid *
).(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++:
null
(lowercase) ornullptr
(C++11 or later) is a null pointer to C++ objects.So to check against
nil
you should either compare againstnil
(orNULL
respectively) explicitly:or let ObjC / C do it implicitly for you:
This works as every expression in C (and with Objective-C being a superset thereof) has an implicit boolean value:
Now when checking for
NSNull
this obviously wouldn't work as[NSNull null]
returns a pointer to a singleton instance ofNSNull
, and notnil
, and therefore it is not equal to0x0
.So to check against
NSNull
one can either use:or (preferred, see comments):
Keep in mind that the latter (utilising a message call) will return
false
ifgetCaption
happens to benil
, which, while formally correct, might not be what you expect/want.Hence if one (for whatever reason) needed to check against both
nil
/NULL
andNSNull
, one would have to combine those two checks: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.
Just check with this code:
This should work.
You should use
if ([myNSString isEqual:[NSNull null]])
This will check if object myNSString is equal to NSNull object.
Preferred Way to check for the
NSNULL
is