2011-04-16 71 views
51

我有一段代码检测NSString是否为NULL,nil等。但是,它崩溃。这里是我的代码:如何检测NSString是否为空?

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..."; 
} 

} 

而这里的错误:

Terminating app due to uncaught exception ' NSInvalidArgumentException ', reason: ' -[NSNull isEqualToString:] : unrecognized selector sent to instance 0x3eba63d4 '

难道我做错了什么?我需要以不同的方式去做吗?

+1

'rowtwo'的数据类型是什么?你为什么要发送'-valueForKey:'? – 2011-04-16 02:47:22

+3

我会留下此评论以供进一步参考:'-valueForKey:'是一种KVC方法。在KVC中,'[NSNull null]'表示没有给定键的值。如果您在不需要KVC的上下文中使用'NSDictionary',请改用'-objectForKey:',否则当给定的键不存在时,它将返回'nil'而不是'[NSNull null]'字典。 – 2011-04-16 03:03:27

+1

关于'-valueForKey:'和'-objectForKey:'之间区别的讨论,请参阅本堆栈溢出问题:http://stackoverflow.com/questions/1062183/objective-c-whats-the-difference-between-objectforkey -and-valueforkey – 2011-04-16 03:04:45

回答

163

目标C的NULL值对象(类型id)是nil

虽然NULL用于C指针(类型void *)。

(在端二者最终但是保持相同的值(0x0)它们在类型上不同。)

目标C

  • nil(所有小写)是空的 指向Objective-C对象
  • Nil(大写)是一个空指针 到Objective-C类
  • NULL(全部大写)是一个空指针 别的C指针,这是)
  • [NSNull null]对于有些情况下使用零是不可能的(添加/接收零到/从NSArray小号例如)

目的-C++

  • 以上皆为,加上:
  • null(小写)nullptrC++ 11或更高版本)是空指针,指向C++对象

所以要检查nil您应该(分别或NULL)比较反对nil明确

if (getCaption == nil) ... 

或让ObjC/ç隐含为你:

if (!getCaption) ... 

这个工作过程中Ç每表达(并用Objective-C的是它们的超集)有一个隐式布尔值:

expression != 0x0 => true 
expression == 0x0 => false 

现在检查NSNull这显然当将不起作用[NSNull null]返回指向单个实例NSNull而不是nil的指针,因此它不等于0x0

所以要检查NSNull一个可以使用:

if ((NSNull *)getCaption == [NSNull null]) ... 

或(首选,见注释):

if ([getCaption isKindOfClass:[NSNull class]]) ... 

请记住,后者(利用消息调用)将返回false如果getCaption碰巧是nil,它虽然正式正确,但可能不是您所期望/想要的。

因此,如果一个(无论何种原因)需要对阵双方nil/NULLNSNull检查,一会要这两个检查相结合:

if (!getCaption || [getCaption isKindOfClass:[NSNull class]]) ... 

如需帮助上形成等效肯定检查参见De Morgan's lawsboolean negation

编辑:NSHipster.com刚刚出版了零之间的细微差别很大的文章,空,等

+2

确实,虽然实际的错误是'[rowtwo valueForKey:@“caption”]'正在返回一个'NSNull'实例而不是'NSString'实例。 – 2011-04-16 02:49:06

+0

@Bavarious:见答案的最后一行。 – Regexident 2011-04-16 02:53:10

+0

谢谢,它的工作原理! – iosfreak 2011-04-16 02:58:14

23

您应该使用

if ([myNSString isEqual:[NSNull null]])

这将检查对象myNSString等于NSNull对象。

+4

由于NSNull是一个单例,你可以直接比较指针:'if(getCaption == [NSNull null])...' – Caleb 2011-04-16 02:55:32

+1

但是与单例比较是一个坏主意!不要这样做= X。 [NSNull null]可能是单身人士,但NSNull与其他任何人一样。 – Dustin 2012-02-29 01:07:21

2
if([getCaption class] == [NSNull class]) 
    ... 

你也可以做

if([getCaption isKindOfClass:[NSNull class]]) 
    ... 

,如果你想成为对抗NSNull的新的子类面向未来。

+1

在这个页面上的所有答案中,只有您最常见的答案是在Xcode 6.1中为我工作,使用名为'body'的NSString属性为null。调试器输出:'_body \t NSString * class name = NSNull \t 0x0000000107279ce0'和'打印广告描述 - > _ body:' – 2014-11-06 02:30:42

6

首选方法来检查NSNULL

if(!getCaption || [getCaption isKindOfClass:[NSNull class]]) 
2

与此代码只是检查:

NSString *object; 

if(object == nil) 

这应该工作。