【问题标题】:How to increment a NSNumber如何增加 NSNumber
【发布时间】:2011-01-25 11:54:21
【问题描述】:

如何增加 NSNumber?

即我的NSNumber++

【问题讨论】:

  • 记住:使用NSNumber *时,一定要检查原始类型是否足够。
  • 令我惊讶的是,没有提供快速/优化方式的答案,因为只是为了增加价值,您需要查询、组合和创建新对象,因此在循环中执行此操作可能会变得耗时.

标签: objective-c


【解决方案1】:

NSNumber 对象是不可变的;你能做的最好的就是获取原始值,增加它然后将结果包装在它自己的NSNumber对象中:

NSNumber *bNumber = [NSNumber numberWithInt:[aNumber intValue] + 1];

【讨论】:

  • 现代语言:1,Objective-C:0。
【解决方案2】:

更新:仅供参考,我个人更喜欢 BoltClock 和 DarkDusts 的单行答案。它们更简洁,不需要额外的变量。


为了增加NSNumber,您必须获取它的值,增加它,并将其存储在新的NSNumber 中。

例如,对于一个持有整数的NSNumber

NSNumber *number = [NSNumber numberWithInt:...];
int value = [number intValue];
number = [NSNumber numberWithInt:value + 1];

或者对于持有浮点数的NSNumber

NSNumber *number = [NSNumber numberWithDouble:...];
double value = [number doubleValue];
number = [NSNumber numberWithDouble:value + 1.0];

【讨论】:

  • 这是我讨厌 Core Data 中的 NSNumber 属性的第一个原因。 NSNumber 使用和执行数学运算非常不方便。
  • 再次 NSNumber 不起作用,而用零初始化给出垃圾值。
  • 抱歉,... 代表什么?那是伪代码引用对吗? XCode 没有 ...
  • @boulder_ruby ... 只是您想要的任何数字的占位符。
【解决方案3】:

对于使用最新版本 Xcode(从 4.4.1、SDK 5.1 开始编写)的任何人,通过使用对象文字,您可以进一步清理代码......

NSNumber *x = @(1);
x = @([x intValue] + 1);
// x = 2

处理装箱和拆箱来做简单的操作还是有点痛苦,但它正在变得更好,或者至少更短。

【讨论】:

  • @softRli 查看clang.llvm.org/docs/ObjectiveCLiterals.html 以查看更多 ObjC 文字!非常方便 imo。
  • 您可以使用 x - @(x.intValue+1),尽管很多人不喜欢使用点符号来调用非属性方法。它更短,但可以称为滥用点符号。
  • @boulder_ruby,这是重新分配。 NSNumber 是不可变的,因此要“增加”该值,您实际上必须将其重新分配给一个新值。
【解决方案4】:

NSNumber 是不可变的,您必须创建一个新实例。

// Work with 64 bit to support very large values
myNSNumber = [NSNumber numberWithLongLong:[myNSNumber longLongValue] + 1];

// EDIT: With modern syntax:
myNSNumber = @([myNSNumber longLongValue] + 1);

【讨论】:

    【解决方案5】:

    把它们放在一起,你就有了:

    myNSNumber = @(myNSNumber.intValue + 1);
    

    【讨论】:

    • 你不是在这里重新分配 myNSNumber 的值吗?我认为这是不允许的,因为 NSNumber 对象是不可变的(?)
    • 你正在创建一个新的 NSNumber 对象。 myNSNumber 是一个指针 (NSNumber *),完成后会有一个新值。
    【解决方案6】:

    我喜欢点表达式,因为它更简洁,这也是 IOS 首先支持它的原因:

    myNSNumber = [NSNumber numberWithInt:myNSNumber.intValue + 1];
    

    【讨论】:

    • 点表示法没有按照您的想法执行,并且有时可能会更慢(如果“属性”(在您的情况下为 intValue)不存在合成访问器,则它可能默认为“valueForKey:”。 intValue 从未定义为 NSNumber 的 @property。
    【解决方案7】:

    如果你用它来存储一个整数值:

    myNSNumber = @(myNSNumber.longLongValue + 1);
    

    对于浮点的东西,简短的回答如下,但这样做是个坏主意,你会失去精度,如果你稍后进行任何类型的比较,比如 [myNSNumber isEqual:@(4.5)] 你可能会感到惊讶:

    myNSNumber = @(myNSNumber.floatValue + 1);
    

    如果您需要对在 Objective-C 中表示为对象的浮点数进行数学运算(即,如果您需要将它们放入数组、字典等中),您应该使用 NSDecimalNumber

    【讨论】:

    • 如果您要投反对票,不妨提出建设性意见并说出原因。
    • 您的回答暗示是 NSNumber 引入了舍入问题。这是不正确的, NSNumber 具有与标量类型相同的舍入行为。您对使用 NSDecimalNumbers 的建议也很烦人。在那里你暗示如果你需要 onmbjective-c 中的第一个公民对象,这些是必要的。但当然也可以在对象上使用 nsnumbers。 NSDecimalNumbers 具有更高的精度,但也可能出现舍入误差。并且: op 询问有关递增的问题,您的答案是浮点数和双数运算。但这些没有增量,因为它们没有自然继承者。
    • @vikingosegundo 它将 NSNumber 转换为导致准确性损失的浮点数,因为 NSNumber 抽象地存储了浮点数为 base2 的数字,所以这不是 NSNumber 的错,而是来回转换的错。并且 NSDecimalNumbers 不会 导致 base10 算术的舍入错误,并且它们 专为算术而设计,请阅读文档。 OP 询问有关增加 NSNumber 的问题,我给了他一个关于积分情况的正确且可读的答案,也给出了浮点情况的答案,但建议不要这样做,然后提出更好的建议。
    • 一个实例可以表示任何可以表示为尾数 x 10 指数的数字,其中尾数是最多 38 位长度的十进制整数,指数是 -128 和 127 之间的整数。 不是每个数字都可以这样表达。 OP还要求轻松递增。 NSDecimalNumber 没有提供。并且您的回答仍然暗示您需要对象空间中的 NSDecimalNumbers 。这是错误的。
    • 伙计,我试图对我的回答提供真正的帮助,并认为否决票是因为我做错了,我想我可能会学到一些新东西。我现在可以看到情况并非如此。您的 cmets 没有任何意义,我建议您阅读有关数字系统的 uo,因为基于 10 的数字系统。 (关于您的报价)不会导致任何以 10 为底的数字的舍入误差,我没有说精度,只是精度,但 128 十进制也有足够的精度。
    【解决方案8】:

    使用一个类别以方便将来使用。这是一个基本的想法。

     - (void)incrementIntBy:(int)ammount {
          self = [NSNumber numberWithInt:(self.intValue + ammount)];
     }
    

    【讨论】:

    • 呃。一个实现了替换self的实例方法的类别?!?这真是太恶心了。为什么不编写一个实例方法,该方法具有非 void 返回的结果 NSNumber。
    • NSNumber 被定义为不可变的,因此该类别方法违反了其假定的不变性(即使替换 self)。一个设计更好的此类类别会改为向 NSNumber 添加一个新的初始化程序,格式为:+numberByIncrementingAmounf:(int)amount;
    【解决方案9】:

    这个问题的答案中有很多很好的信息。我在我的代码中使用了选定的答案并且它有效。然后我开始阅读其余的帖子并大大简化了代码。如果你不熟悉 Xcode 5 中引入的符号变化,阅读起来会有点困难,但它更清晰。我可能可以只写一行,但是很难弄清楚我在做什么。

    我将 NSNumber 存储在字典中,我想增加它。我明白了,将其转换为 int,在将其转换为 NSNumber 时将其递增,然后将其放回字典中。

    旧代码

     NSNumber *correct = [scoringDictionary objectForKey:@"correct"];
     int correctValue = [correct intValue];
     correct = [NSNumber numberWithInt:correctValue + 1];
     [scoringDictionary removeObjectForKey:@"correct"];
     scoringDictionary[@"correct"] = correct;
    

    新代码

    NSNumber *correct = [scoringDictionary objectForKey:@"correct"];
    scoringDictionary[@"correct"] = @(correct.intValue + 1);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-22
      • 1970-01-01
      相关资源
      最近更新 更多