如何检测NSString是否为null? [英] How to detect if NSString is null?

查看:199
本文介绍了如何检测NSString是否为null?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一段代码可以检测NSStringNULLnil等.但是,它崩溃了.这是我的代码:

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

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/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.

这篇关于如何检测NSString是否为null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆