检查 NSNumber 是否为空

发布于 2024-09-24 04:01:04 字数 1573 浏览 2 评论 0原文

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

OK nil 很简单:

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

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

if ([myNumber intValue]==0)
   doSomething

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

示例 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。那么它包含任意数字?

How do I check if a NSNumber object is nil or empty?

OK nil is easy:

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

But if the object has been created, but there is no value in it because an assignment failed, how can I check this? Use something like this?

if ([myNumber intValue]==0)
   doSomething

Is there a general method for testing objects on emptiness like for NSString available (see this post)?

Example 1

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

Which value does emptyNumber contain? How can I check if emptyNumber is empty?

Example 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;

What happens if I use this after emptyNumber was set to nil?

[emptyNumber intValue]

Do I get zero?

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

Like this way NSLog is never called. myEmptyValue is not nil and not NSNull. So it contains an arbitrary number?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

荭秂 2024-10-01 04:01:04

NSValueNSNumber、... 应该从一个值创建并始终保存一个值。仅当 0 等特定值不在您正在使用的有效值范围内时,测试才有效。

在极少数情况下,如果您有一个表示“无效”“未设置”的值,并且您不能使用 < code>nil (例如,使用标准容器)您可以使用 NSNull 代替。

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

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

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

但请注意,您不能简单地插入(或删除)该值,除非您需要区分 nil (即不在容器中)和,比如说,“无效”:

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

至于第二个示例-intValue 为您提供 0 - 但仅仅是因为向 nil 发送消息会返回 0。您还可以获取 0,例如对于 NSNumber,其 intValue 之前设置为 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
}

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

选项#3:

在极少数情况下,将所有键保留在字典中并用不同的值表示“空”会更方便。如果您无法使用数字范围中的一个,我们必须添加不同的内容,因为 NSNumber 没有“空”的概念。 Cocoa 已经为此类情况提供了 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;
    // ...
}

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

NSValue, NSNumber, ... are supposed to be created from a value and to always hold one. Testing for a specific value like 0 only works if it isn't in the range of valid values you are working with.

In the rare case where code is more straight-forward to work with if you have a value that represents "invalid" or "not set" and you can't use nil (e.g. with the standard containers) you can use NSNull instead.

In your first example this could be:

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

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

But note that you can simply not insert (or remove) that value unless you need to differentiate nil (i.e. not in the container) and, say, "invalid":

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

As for the second example, -intValue gives you 0 - but simply because sending messages to nil returns 0. You could also get 0 e.g. for a NSNumber whose intValue was set to 0 before, which could be a valid value.
As i already wrote above, you can only do something like this if 0 is not a valid value for you. Note the for you, what works best completely depends on what your requirements are.

Let me try to summarize:

Option #1:

If you don't need all values from the numbers range, you could use one (0 or -1 or ...) and -intValue / ... to specifically represent "empty". This is apparently not the case for you.

Option #2:

You simply don't store or remove the values from the container if they are "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
}

This however means that there is no difference between keys that are empty and keys that never exist or are illegal.

Option #3:

In some rare cases its more convenient to keep all keys in the dictionary and represent "empty" with a different value. If you can't use one from the number range we have to put something differently in as NSNumber doesn't have a concept of "empty". Cocoa already has NSNull for such cases:

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

This option now allows you to differentiate between "empty", "not empty" and "not in the container" (e.g. illegal key).

梨涡 2024-10-01 04:01:04

NSNumber 要么是 nil,要么它包含一个数字,中间没有任何内容。 “空”是一个依赖于特定对象语义的概念,因此寻找一般的空检查是没有意义的。

至于您的示例,发生了几件事:

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 即可。

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

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

将变成这样:

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

希望这会有所帮助。

NSNumber is either nil, or it contains a number, nothing in between. “Emptiness” is a notion that depends on the semantics of the particular object and therefore it makes no sense to look for a general emptiness check.

As for your examples, there are several things going on:

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

The NSLog will print 0 here, but only because there’s an intValue method in NSString. If you change the message to something that only NSNumber can do, the code will fail:

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

This will throw:

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

Which means you are not getting some general “empty” value back from the hash, you just get the NSString you stored there.

When you have an empty (== nil) NSNumber and send it a message, the result will be zero. That’s simply a language convention that simplifies code:

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

Will turn into this:

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

Hope this helps.

白色秋天 2024-10-01 04:01:04

处理 Swift 2.0 和 Parse:

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

就我而言,我必须:

    let myNumberIntValue = myNumber!.intValue

Dealing with Swift 2.0 and Parse:

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

In my case, I then had to:

    let myNumberIntValue = myNumber!.intValue
内心激荡 2024-10-01 04:01:04

NSNumber 是不可变的,只能使用工厂方法或初始方法来创建,并为它们提供一些数值。据我所知,不可能以“空”NSNumber 结束,除非你数到 0。

NSNumbers are immutable and can only be created with either a factory method or initial method that gives them some numeric value. As far as I know it is not possible to end up with an 'empty' NSNumber, unless you count 0.

自由如风 2024-10-01 04:01:04

从字典中获取一个对象,期望它是一个 NSNumber,然后让它返回一个 nil 对象,这是很常见的(至少对我来说)。如果发生这种情况并且您执行 intValue ,它将崩溃。

我所做的是设置零保护,因为我宁愿获得默认值也不愿崩溃。

一种方法是:

-(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]];

It's very common (for me at least) to get an object out of a dictionary, expect that it's going to be an NSNumber and then have it return a nil object. If this happens and you do an intValue it will crash.

What I do is setup nil protection because I'd rather get a default value than a crash.

One way is:

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

And I have one just like it for floats. Then you at least get your default value. Another way is to just create a method for nil protection..

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

That one you'd call like this:

NSNumber *value = [self nilProtectionForNumber:[dict objectForKey:keyThatShouldBeNSNumber] withDefault:[NSNumber numberWithInt:0]];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文