Reputation: 6178
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?
Upvotes: 0
Views: 46
Reputation: 299455
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.
Upvotes: 2
Reputation: 6178
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;
}
Upvotes: 0