如何检测NSString是否为null? [英] How to detect if NSString is null?
问题描述
我有一段代码可以检测NSString
是NULL
,nil
等.但是,它崩溃了.这是我的代码:
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...";
}
}
这是错误:
由于未捕获的异常'
NSInvalidArgumentException
',正在终止应用程序,原因:'-[NSNull isEqualToString:]
:无法识别的选择器已发送到实例0x3eba63d4
'
我做错什么了吗?我需要用其他方式做吗?
Objective-C对象(类型id
)的NULL
值为nil
.
NULL
用于 C指针(类型void *
).
(最后,两者最终都拥有相同的值(0x0
).但是它们的类型不同.)
在 Objective-C 中:
-
nil
(全部小写)为空 指向 Objective-C对象的指针. -
Nil
(大写)是空指针 到 Objective-C类. -
NULL
(全部大写)是指向的空指针 其他任何(即 C指针). -
[NSNull null]
是 singleton (单例),用于无法使用nil的情况(例如,在NSArray
中添加nil或从中接收nil)
在 Objective-C ++ 中:
- 以上所有,以及:
-
null
(小写字母)或nullptr
( C ++ 11 或更高版本)是指向 C ++对象的空指针.
因此要与nil
进行比较,您应该与nil
(或分别为NULL
)进行比较明确:
if (getCaption == nil) ...
或让 ObjC / C 为您进行隐含的操作:
if (!getCaption) ...
这适用于 C 中的每个表达式(并且 Objective-C 是其超集)具有隐式布尔值:
expression != 0x0 => true
expression == 0x0 => false
现在,当检查NSNull
时,这显然不起作用,因为[NSNull null]
返回指向NSNull
而不是nil
的单例实例的指针,因此它不等于0x0
. /p>
因此要检查NSNull
,可以使用:
if ((NSNull *)getCaption == [NSNull null]) ...
或(首选,请参见评论):
if ([getCaption isKindOfClass:[NSNull class]]) ...
请记住,如果getCaption
恰好是nil
,则后者(使用消息调用)将返回false
,尽管在形式上正确,但可能并非您期望/想要的.
因此,如果出于某种原因(无论出于何种原因)需要进行检查 nil
/NULL
和 NSNull
,则必须将这两项检查结合起来:
if (!getCaption || [getCaption isKindOfClass:[NSNull class]]) ...
编辑: NSHipster.com 刚刚发表了一篇有关细微差别的文章在nil,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 instance0x3eba63d4
'
Am I doing something wrong? Do I need to do it a different way?
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/fromNSArray
s e.g.)
In Objective-C++:
- All of the above, plus:
null
(lowercase) ornullptr
(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.
这篇关于如何检测NSString是否为null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!