Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect if NSString is null?

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 instance 0x3eba63d4'

Am I doing something wrong? Do I need to do it a different way?

like image 706
iosfreak Avatar asked Apr 16 '11 02:04

iosfreak


People also ask

How do I know if NSString is empty?

You can check if [string length] == 0 . This will check if it's a valid but empty string (@"") as well as if it's nil, since calling length on nil will also return 0. There are some very rare NSStrings where this will result in a false negative (saying the string isn't empty, when, for practical purposes, it is).

How do you find nil in Objective C?

Any message to nil will return a result which is the equivalent to 0 for the type requested. Since the 0 for a boolean is NO, that is the result. Show activity on this post. Hope it helps.

Do I need to release NSString?

If you create an object using a method that begins with init, new, copy, or mutableCopy, then you own that object and are responsible for releasing it (or autoreleasing it) when you're done with it. If you create an object using any other method, that object is autoreleased, and you don't need to release it.

What is NSString?

A static, plain-text Unicode string object that bridges to String ; use NSString when you need reference semantics or other Foundation-specific behavior.


2 Answers

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/from NSArrays e.g.)

In Objective-C++:

  • All of the above, plus:
  • null (lowercase) or nullptr (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.

like image 173
Regexident Avatar answered Sep 25 '22 12:09

Regexident


You should use

if ([myNSString isEqual:[NSNull null]])

This will check if object myNSString is equal to NSNull object.

like image 38
ludesign Avatar answered Sep 24 '22 12:09

ludesign