ios - NSDecimalNumberOverflowException - 问题

标签 ios objective-c nsdecimalnumber

我有 UITextField,其所有者是文本字段的代表。我已将 UITextField 声明如下:

 self.thresholdValueTextField.delegate = self;

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setMaximumFractionDigits:2];
[numberFormatter setMinimumFractionDigits:2];

self.thresholdValueTextField.text = [numberFormatter stringFromNumber:[NSNumber numberWithInt:0]];

当用户继续按下后退按钮时,即使字符串为 $0.00,我的应用程序由于以下错误而崩溃:
*** Terminating app due to uncaught exception 'NSDecimalNumberOverflowException', reason: 'NSDecimalNumber overflow exception'    

下面给出了处理 textField 的代码: shouldChangeCharactersInRange: 委托(delegate)方法:
- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string
{
  NSInteger MAX_DIGITS = 10; // $999,999,999.99

  NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
  [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
  [numberFormatter setMaximumFractionDigits:2];
  [numberFormatter setMinimumFractionDigits:2];

  NSString *stringMaybeChanged = [NSString stringWithString:string];
  if (stringMaybeChanged.length > 1)
  {
     NSMutableString *stringPasted = [NSMutableString stringWithString:stringMaybeChanged];

     [stringPasted replaceOccurrencesOfString:numberFormatter.currencySymbol
                                  withString:@""
                                     options:NSLiteralSearch
                                       range:NSMakeRange(0, [stringPasted length])];

     [stringPasted replaceOccurrencesOfString:numberFormatter.groupingSeparator
                                  withString:@""
                                     options:NSLiteralSearch
                                       range:NSMakeRange(0, [stringPasted length])];

     NSDecimalNumber *numberPasted = [NSDecimalNumber decimalNumberWithString:stringPasted];
     stringMaybeChanged = [numberFormatter stringFromNumber:numberPasted];
  }

   UITextRange *selectedRange = [textField selectedTextRange];
   UITextPosition *start = textField.beginningOfDocument;
   NSInteger cursorOffset = [textField offsetFromPosition:start toPosition:selectedRange.start];
   NSMutableString *textFieldTextStr = [NSMutableString stringWithString:textField.text];
   NSUInteger textFieldTextStrLength = textFieldTextStr.length;

   [textFieldTextStr replaceCharactersInRange:range withString:stringMaybeChanged];

   [textFieldTextStr replaceOccurrencesOfString:numberFormatter.currencySymbol
                                  withString:@""
                                     options:NSLiteralSearch
                                       range:NSMakeRange(0, [textFieldTextStr length])];

   [textFieldTextStr replaceOccurrencesOfString:numberFormatter.groupingSeparator
                                  withString:@""
                                     options:NSLiteralSearch
                                       range:NSMakeRange(0, [textFieldTextStr length])];

   [textFieldTextStr replaceOccurrencesOfString:numberFormatter.decimalSeparator
                                  withString:@""
                                     options:NSLiteralSearch
                                       range:NSMakeRange(0, [textFieldTextStr length])];

   if (textFieldTextStr.length <= MAX_DIGITS)
   {
    NSDecimalNumber *textFieldTextNum = [NSDecimalNumber decimalNumberWithString:textFieldTextStr];
    NSDecimalNumber *divideByNum = [[[NSDecimalNumber alloc] initWithInt:10] decimalNumberByRaisingToPower:numberFormatter.maximumFractionDigits];
    NSDecimalNumber *textFieldTextNewNum = [textFieldTextNum decimalNumberByDividingBy:divideByNum];
    NSString *textFieldTextNewStr = [numberFormatter stringFromNumber:textFieldTextNewNum];

    textField.text = textFieldTextNewStr;

    if (cursorOffset != textFieldTextStrLength)
    {
        NSInteger lengthDelta = textFieldTextNewStr.length - textFieldTextStrLength;
        NSInteger newCursorOffset = MAX(0, MIN(textFieldTextNewStr.length, cursorOffset + lengthDelta));
        UITextPosition* newPosition = [textField positionFromPosition:textField.beginningOfDocument offset:newCursorOffset];
        UITextRange* newRange = [textField textRangeFromPosition:newPosition toPosition:newPosition];
        [textField setSelectedTextRange:newRange];
     }
   }

  return NO;
}

我可以知道是什么导致了这个错误吗?

最佳答案

问题在于 [NSDecimalNumber Zero] 和 NaN 出现的 DecimalNumberByDividingBy。

更新 DecimalNumberByDivindingBy 的代码解决了它

 NSDecimalNumber *textFieldTextNewNum;
 if ([textFieldTextNum compare:[NSDecimalNumber zero]] == NSOrderedSame || [[NSDecimalNumber notANumber] isEqualToNumber:textFieldTextNum]) {
        textFieldTextNewNum = [NSDecimalNumber zero];
 }else{
        textFieldTextNewNum = [textFieldTextNum decimalNumberByDividingBy:divideByNum];
 }

关于ios - NSDecimalNumberOverflowException - 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30339319/

相关文章:

javascript - 在 React Native 的 ScrollView 中设置 contentInset 和 contentOffset

ios - 捕获两个图像并将其显示到两个 UIImageView

ios - 无法使 mediaPlayer View 在 UIView 内水平旋转

objective-c - 替代 UIDevice 的 UniqueIdentifier - iOS 的网络接口(interface) ID 是什么?

iOS:NSDecimalNumber:没有得到预期的结果

json - AlamoFire responseJSON 十进制精度

ios - NSLocationAlwaysAndWhenInUseUsageDescription 的字符限制是多少?

objective-c - 多个 Controller 和半共享对象之间的所有权和引用模式?

iphone - 有没有办法从新的模态视图访问启动模态视图的 View Controller ?

iphone - 通过核心数据计算小数值的总和无法正常工作?