0

I had written a NSString category to judge a string whether an empty string:

- (BOOL)isEmptyString {
    if ([self isEqual:[NSNull null]] || self == NULL || self == nil || [self isEqualToString:@""] || self.length == 0)
    {
        return YES;
    }
    return NO;
}

However,when a string is a nil string,returned NO:

NSString *a = nil;
if ([a isEmptyString]) {
    NSLog(@"is empty");
} else {
    NSLog(@"not empty");
}

Console printed “not empty”.

Why returned NO?the string is nil so it's meet the condition self == nil,YES should been return,isn’t it?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
无夜之星辰
  • 5,426
  • 4
  • 25
  • 48
  • 1
    if string is nil, how you gonna call that method or function ? – Blind Ninja Sep 26 '18 at 10:00
  • Possible duplicate of [Calling a method on an uninitialized object (null pointer)](https://stackoverflow.com/questions/2696891/calling-a-method-on-an-uninitialized-object-null-pointer) – Larme Sep 26 '18 at 15:32

2 Answers2

2

When you send a messages to nil, the result is always "zero-ish." That means it's void, nil, zero, or false, or whatever "evaluating zero in this context" would mean. You cannot write code that changes that. It is a fundamental part of how objc_msgSend works (and is closely related to how message dispatching in ObjC works).

The key point to understand is that ObjC uses dynamic dispatch. It does not rely on compile-time types to decide what to call. It sends a message to the actual object, and the object decides what to do with it (and this can be changed at runtime by several mechanisms). As a special case, the "nil" object (which doesn't really exist; it's just "a pointer to 0x00"), always returns a zero-ish result for every message. So at runtime, it does not matter that a is of type NSString*. It's just an object, and it respond to messages, and if it's nil then it's going to respond to messages in a nil-like way.

So the answer is "do not do this." The idiomatic way to check for "empty string" is:

if ([string length] == 0) { ... }

This idiom relies on the fact that [nil length] will return 0.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
0

When a string is nil,in fact,it is only a nil,not a string. You send a message to a nil,nothing would happen.

So,if you want to use a category to judge a string whether an empty string,you can take it as a parameter,e.g.:

+ (BOOL)judgeIsEmptyString:(NSString *)string {
    if ([string isEqual:[NSNull null]] || string == NULL || string == nil || [string isEqualToString:@""] || string.length == 0)
    {
        return YES;
    }
    return NO;
}
无夜之星辰
  • 5,426
  • 4
  • 25
  • 48
  • You should update your answer showing how you use this method with your example. – rmaddy Sep 26 '18 at 15:28
  • Yes and no. By default it returns false, see there: https://stackoverflow.com/a/2696909/1801544 That's why it response `NO`. – Larme Sep 26 '18 at 15:32