1

The problem I am trying to solve is to convert nil strings into empty strings so I can put that as a value in NSDictionary.

I have the following code:

//Accessed in class  
prospect.title = [self.titleLabel.text emptyWhenNil];

// NSString+Additions Category

-(NSString *) emptyWhenNil
{
   if(self == nil)
      return @"";

   return self;
 }

But for some reason the emptyWhenNil method is never even invoked!! I am lost..

cheesemacfly
  • 11,622
  • 11
  • 53
  • 72
john doe
  • 9,220
  • 23
  • 91
  • 167

3 Answers3

13

The problem is, when your string pointer is nil, you have no object to send that category message to. Messages to nil are not executed (and return nil) in Objective-C.

If you want to put "null" objects into a collection, such as an NSDictionary, or NSArray, you can use the NSNull class instead.

Alternatively you could implement this method as a class method:

+ (NSString *)emptyStringIfNil:(NSString *)str {
    if (!str) return @"";
    return str;
}

You would then call this as

prospect.title = [NSString emptyStringIfNil:self.titleLabel.text];
DrummerB
  • 39,814
  • 12
  • 105
  • 142
  • Not really ignored, they return `nil`, `NO` or `0`. – Sulthan Apr 05 '13 at 14:26
  • 1
    Yes, but certainly not executed. – DrummerB Apr 05 '13 at 14:28
  • Thanks @DrummerB!! Worked like a charm :) – john doe Apr 05 '13 at 14:35
  • @DrummerB Messages are never executed, they are sent. Here they are sent to `nil` which is semantically not different from sending the message to an object. The messages are not ignored and ARE executed. – Sulthan Apr 05 '13 at 14:36
  • @Sulthan I know Obj-C terminology (as Apple suggests), but very often people use other terminologies and talk about "calling" or "executing" methods. I don't think it's worth arguing. Btw, your first and last sentences are in direct contradiction to each other. – DrummerB Apr 05 '13 at 14:46
  • @DrummerB There are times when you can simplify the terminology and use the words "call" or "execute". In this case you shouldn't. However, the problem I am having is that "message to nil are not executed" is wrong. They are sent and received by `nil`. See http://stackoverflow.com/questions/156395/sending-a-message-to-nil – Sulthan Apr 05 '13 at 14:57
  • @Sulthan How could "nothing" be a receiver? Sending messages to `nil` is a special case. They are executed as in having a return value, but the method itself is not executed. In the question you posted, there is this answer: http://stackoverflow.com/a/160432/343340 – DrummerB Apr 05 '13 at 15:03
  • It is more accurate to say that messages to nil are short-circuited by the messenger. No methods are executed, but it the call isn't ignored. Note that the messenger on some platforms has a hook for adding alternative mechanisms for handling messages to nil. – bbum Apr 05 '13 at 15:54
1

If the NSString pointer is nil, the method will not be called on it, what you can do is create a static method:

+ (NSString *) emptyIfNil:(NSString *) str
{
    return str == nil ? @"" : str;
}
MByD
  • 135,866
  • 28
  • 264
  • 277
1

If the string is nil, there is no self to execute the method on. The default behaviour of the runtime in this situation is to return a default nil value.

You should implement this as a static method instead. Something like this:

+ (NSString *)emptyStringIfNil:(NSString *)input
{
    return input ? input : @"";
}
Mike Weller
  • 45,401
  • 15
  • 131
  • 151
  • Wow that's a bit verbose writing it out in full like that - `return input ?: @"";` :) – Paul.s Apr 05 '13 at 14:43
  • As far as I know, using `?:` with no left-hand 'then' expression is a GNU extension and will not work with all compilers. – Mike Weller Apr 05 '13 at 14:49
  • Ok it wasn't as easy as I thought it would be to google but it's in the [API docs](http://clang.llvm.org/doxygen/classclang_1_1BinaryConditionalOperator.html) - `ConditionalOperator - The ?: ternary operator. The GNU "missing middle" extension is a BinaryConditionalOperator.` – Paul.s Apr 05 '13 at 14:57
  • 1
    It's still an extension, and not standard or portable. Some people have extensions turned off with warnings and other compiler flags. I wouldn't personally use it in a SO answer or in any library code. – Mike Weller Apr 05 '13 at 15:01