检查NSNumber是否为空

tes*_*ing 18 iphone cocoa-touch objective-c nsnumber

如何检查NSNumber对象是否为空?

好的很容易:

NSNumber *myNumber;
if (myNumber == nil)
    doSomething
Run Code Online (Sandbox Code Playgroud)

但是如果对象已经创建,但由于分配失败而没有值,我该如何检查?用这样的东西?

if ([myNumber intValue]==0)
   doSomething
Run Code Online (Sandbox Code Playgroud)

是否有一种通用的方法来测试空虚上的对象,例如NSString可用(参见这篇文章))?

例1

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:@"" forKey:@"emptyValue"];
NSNumber *emptyNumber = [dict objectForKey:@"emptyValue"];
Run Code Online (Sandbox Code Playgroud)

哪个值emptyNumber包含?我该怎么检查emptyNumber为空?

例2

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:@"" forKey:@"emptyValue"];
NSString *myString = [dict objectForKey:@"emptyValue"];
if (myString == nil || [myString length] == 0)
    // got an empty value
    NSNumber *emptyNumber=nil;
Run Code Online (Sandbox Code Playgroud)

如果我之后使用它会发生什么 emptyNumber设置为nil?

[emptyNumber intValue]
Run Code Online (Sandbox Code Playgroud)

我得到零吗?

例3

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:@"" forKey:@"emptyValue"];
NSNumber *myEmptyValue = [dict objectForKey:@"emptyValue"];
if (myEmptyValue == nil)
    // NSLog is never called
    NSLog(@"It is empty!");
Run Code Online (Sandbox Code Playgroud)

就像这样,永远不会调用NSLog.myEmptyValue不是nil也不是NSNull.那么它包含一个任意数字?

Geo*_*che 12

NSValue,, NSNumber...应该是从一个值创建并始终保持一个.测试特定值0仅在不在您正在使用的有效值范围内时才有效.

在极少数情况下,如果您有一个代表"无效""未设置"的值并且您无法使用nil(例如使用标准容器),则代码可以更直接地使用,您可以使用NSNull.

在您的第一个示例中,这可能是:

[dict setValue:[NSNull null] forKey:@"emptyValue"];

if ([dict objectForKey:@"emptyValue"] == [NSNull null]) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

但请注意,除非您需要区分nil(即不在容器中)和"无效",否则您不能插入(或删除)该值:

if ([dict objectForKey:@"nonExistent"] == nil) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

至于第二个例子,-intValue给你0- 但仅仅是因为发送消息nil返回0.您也可以获得0例如NSNumberintValue设置为0之前的值,这可能是有效值.
正如我上面已经写过的那样,如果0 不是一个有效的值,你只能这样做.请注意,对您而言,最有效的方法完全取决于您的要求.

让我试着总结一下:

选项1:

如果您不需要数字范围内的所有值,则可以使用一个(0-1或......)和-intValue/ ...来专门表示"空".这显然不是你的情况.

选项#2:

如果它们是"空",您只是不存储或删除容器中的值:

// add if not empty:
[dict setObject:someNumber forKey:someKey];    
// remove if empty:
[dict removeObjectForKey:someKey];
// retrieve number:
NSNumber *num = [dict objectForKey:someKey];
if (num == nil) {
    // ... wasn't in dictionary, which represents empty
} else {
    // ... not empty
}
Run Code Online (Sandbox Code Playgroud)

然而,这意味着空的键和从不存在或非法的键之间没有区别.

选项#3:

在一些罕见的情况下,将所有键保存在字典中并使用不同的值表示"空"更方便.如果您不能使用数字范围中的一个,我们必须使用不同的东西,因为NSNumber没有"空"的概念.可可已经有NSNull这样的情况:

// set to number if not empty:
[dict setObject:someNumber forKey:someKey];
// set to NSNull if empty:
[dict setObject:[NSNull null] forKey:someKey];
// retrieve number:
id obj = [dict objectForKey:someKey];
if (obj == [NSNumber null]) {
    // ... empty
} else { 
    // ... not empty
    NSNumber *num = obj;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

此选项现在允许您区分"空","非空""不在容器中"(例如非法密钥).