检查NSNumber是否为空

时间:2010-09-15 10:04:33

标签: iphone objective-c cocoa-touch nsnumber

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

好的没有问题:

NSNumber *myNumber;
if (myNumber == nil)
    doSomething

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

if ([myNumber intValue]==0)
   doSomething

是否有一种通用方法可以测试空虚对象,例如NSString可用(请参阅此post)?

示例1

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:@"" forKey:@"emptyValue"];
NSNumber *emptyNumber = [dict objectForKey:@"emptyValue"];

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;

如果我在emptyNumber设置为nil后使用此功能会发生什么?

[emptyNumber intValue]

我得零吗?

示例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!");

就像这样,永远不会调用NSLog。 myEmptyValue不是nil而不是NSNull。所以它包含一个任意数字?

5 个答案:

答案 0 :(得分:12)

NSValueNSNumber,...应该从值创建并始终保持一个。只有在0之类的特定值不在您正在使用的有效值范围内时,才能对其进行测试。

在极少数情况下,如果您的代码“无效”“未设置”并且您可以',那么代码可以更直接地使用使用nil(例如使用标准容器),您可以改为使用NSNull

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

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

if ([dict objectForKey:@"emptyValue"] == [NSNull null]) {
    // ...
}

但请注意,您不能插入(或删除)该值,除非您需要区分nil(即不在容器中),例如“invalid”:< / p>

if ([dict objectForKey:@"nonExistent"] == nil) {
    // ...
}

对于第二个示例-intValue为您提供0 - 但仅仅因为向nil发送消息会返回0。您也可以获得0,例如对于之前NSNumber设置为intValue的{​​{1}},可以是有效值。
正如我上面已经写过的那样,如果0 不是您的有效值,则只能执行此类操作。请注意为您,最有效的方法完全取决于您的要求。

让我尝试总结

选项#1:

如果您不需要数字范围内的所有值,则可以使用一个(00或...)和-1 / ...来明确表示 “空”。显然情况并非如此。

选项#2:

如果“为空”,您只是不存储或删除容器中的值:

-intValue

但这意味着空键和从不存在或非法的键之间没有区别。

选项#3:

在极少数情况下,将所有键保留在字典中并使用不同的值表示“empty”更方便。如果您不能使用数字范围中的一个,我们必须使用不同的内容,因为// 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 } 没有“空”的概念。对于这种情况,Cocoa已经NSNumber

NSNull

此选项现在允许您区分“空”“非空”“不在容器中”(例如非法)键)。

答案 1 :(得分:3)

NSNumbernil,或者它包含一个数字,两者之间没有任何内容。 “空虚”是一个取决于特定对象的语义的概念,因此寻找一般空虚检查是没有意义的。

至于你的例子,有几件事情在继续:

NSMutableDictionary *hash = [NSMutableDictionary dictionary];
[hash setObject:@"" forKey:@"key"];
NSNumber *number = [hash objectForKey:@"key"];
NSLog(@"%i", [number intValue]);

NSLog会在此处打印0,但仅限于intValue中有NSString方法。如果您将邮件更改为仅NSNumber可以执行的操作,则代码将失败:

NSLog(@"%i", [number unsignedIntValue]);

这将抛出:

-[NSCFString unsignedIntValue]: unrecognized selector sent to instance 0x303c

这意味着您从哈希值中获取一些常规“空”值,您只需获得存储在那里的NSString

当您有空(== nilNSNumber并向其发送消息时,结果将为零。这只是一种简化代码的语言约定:

 (array != nil && [array count] == 0)
 (someNumber == nil ? 0 : [someNumber intValue])

将变成这个:

 ([array count] == 0)
 ([someNumber intValue])

希望这有帮助。

答案 2 :(得分:0)

NSNumber是不可变的,只能使用工厂方法或初始方法创建,为它们提供一些数值。据我所知,除非你算上0,否则不可能得到一个'空'的NSNumber。

答案 3 :(得分:0)

对于从字典中获取对象非常常见(至少对我而言),期望它将是一个NSNumber,然后让它返回一个nil对象。如果发生这种情况并且你做了一个intValue就会崩溃。

我所做的是设置nil保护,因为我宁愿得到默认值而不是崩溃。

一种方法是:

-(int) intForDictionary:(NSDictionary *)thisDict objectForKey: (NSString *)thisKey withDefault: (int)defaultValue
{
    NSNumber *thisNumber = [thisDict objectForKey:thisKey];
    if (thisNumber == nil) {
        return defaultValue;
    }
    return [thisNumber intValue];
}

我有一个就像花车一样。然后你至少得到你的默认值。另一种方法是创建一个无保护的方法..

-(NSNumber *)nilProtectionForNumber: (NSNumber *)thisNumber withDefault: (NSNumber *)defaultNumber
{
    if (thisNumber) {
        return thisNumber;
    }
    else
        return defaultNumber;
}

你打电话的那个:

NSNumber *value = [self nilProtectionForNumber:[dict objectForKey:keyThatShouldBeNSNumber] withDefault:[NSNumber numberWithInt:0]];

答案 4 :(得分:0)

处理Swift 2.0和Parse:

var myNumber = yourArray!.objectForKey("yourColumnTitle")
    if (myNumber == nil) {
    myNumber = 0
      }

就我而言,我不得不:

    let myNumberIntValue = myNumber!.intValue