iOS的8号转换/格式错误? (无法重现)错误、格式、iOS

2023-09-09 21:16:02 作者:易缕烊光千人玺爱

下面的方法需要从的UITextField和格式它显示输入。这code有完美地工作了多年,但问题只是报告了iPhone 6加使用的是iOS 8.1。它发生的每一次的用户,但我一直无法重现它。我相信它有做的NSNumber / NSDecimalNumber转换和格式化在iOS 8,也许是一个64位的应用程序/设备。

The following method takes input from a UITextField and formats it for display. This code has worked flawlessly for years, but a problem was just reported on the iPhone 6 Plus using iOS 8.1. It happens every time for the user but I have not been able to reproduce it. I believe it has to do with NSNumber/NSDecimalNumber conversions and formatting on iOS 8, perhaps for a 64-bit app/device.

用于输入键盘是一个数字键盘,以便可以输入到文本字段的仅文本包括数字0-9和删除。

The keyboard used for input is a number pad, so the only text that can be entered into the textfield are the numbers 0-9 and "delete".

根据用户,这是发生了什么:

According to the user, this is what is happening:

我试图进入$ 250的预算金额。当我拉起来   最初是显示0.00。然后,当我进入2,它然后显示   220.02然后当我进入5它说2,200.25然后当我进入0谈到了22,002.50如果我试图抹掉任何数字就拿出   有一个非常庞大的数字。

I am trying to enter a budget amount of $250. When I pull it up initially is shows 0.00. Then as soon as I enter 2, it then show 220.02 then when I enter the 5 it says 2,200.25 then when I enter the 0 it comes up with 22,002.50 if I try to erase any numbers it come up with a really large number.

在code以下工作完全与iOS 8.1,据我已经测试,每一个设备上的模拟器,包括iPhone 6加。它也可以在iPhone 5S设备(64位)与iOS 8.1。我没有一个iPhone 6 Plus器件。

The code below works perfectly with iOS 8.1, as far as I have tested, on every device in the simulator, including the iPhone 6 Plus. It also works in the iPhone 5S device (64-bit) with iOS 8.1. I do not have an iPhone 6 Plus device.

我缺少的东西,有人认为可能会造成这个错误?

Am I missing something that someone sees might be causing this error?

编辑: 难道这可能是因为decimalNumberWithMantissa参数应无符号长很长,我用NSInteger的?这会导致问题,如果是的话,为什么它的工作,直到的iOS 8.1的iPhone 6加?如果我能我会检查这个自己...

Could this possibly be because decimalNumberWithMantissa parameter should be unsigned long long and I am using NSInteger? Would this cause the problem, and if so, why has it worked until iOS 8.1 on iPhone 6 Plus? I would check this myself if I could...

该entryField的UITextField初始化如下:

The entryField UITextField is initialized as follows:

entryField.text = [NSString stringWithFormat:@"%@", [[[ObjectsHelper sharedManager] currencyFullFormatter] stringFromNumber:[NSDecimalNumber zero]]];

和这里的相关code休息:

and here is the rest of the relevant code:

#define MAX__NUMBER_LENGTH 10

- (BOOL)textField:(UITextField *)textFieldHere shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    __ENTERING_METHOD__
    NSMutableString *mstring = [[NSMutableString alloc] initWithString:[entryField text]];

    if([string length] > 0){
        //add case
        [mstring insertString:string atIndex:range.location];
    }
    else {
        //delete case - the length of replacement string is zero for a delete
        [mstring deleteCharactersInRange:range];
    }

    NSString *clean_string = [[mstring componentsSeparatedByCharactersInSet:
                               [[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
                              componentsJoinedByString:@""];

    //clean up mstring since it's no longer needed


    if ((clean_string.length >= MAX__NUMBER_LENGTH && range.length == 0) || ([clean_string length] == 0 && [string isEqualToString:@"0"]))
    {
        return NO; // return NO to not change text
    }
    else {

        //get the cleaned price in the form of a NSNumber - it has not yet been scaled
        NSNumber *priceNumberBeforeScale = [[DateHelper decimalFormatter] numberFromString:clean_string];
        self.budgetIntNumber = priceNumberBeforeScale;

        //get the cleaned price in the form of an integer - it has not yet been scaled
        NSInteger priceIntBeforeScale = [priceNumberBeforeScale integerValue];

        //scale the price for currency
        NSDecimalNumber *priceScaled = [NSDecimalNumber decimalNumberWithMantissa:priceIntBeforeScale exponent:(0-[[[ObjectsHelper sharedManager] currencyScale] integerValue]) isNegative:NO];

        //now format the price for currency
        //and get the grouping separators added in and put it in the UITextField
        entryField.text = [[[ObjectsHelper sharedManager] currencyFullFormatter] stringFromNumber:priceScaled];

        //always return no since we are manually changing the text field
        return NO;
    }
}

从DateHelper.m:

From DateHelper.m:

+ (NSNumberFormatter *)decimalFormatter {   

        __ENTERING_METHOD__
        NSNumberFormatter *decimalFormatter = [[NSNumberFormatter alloc] init];
        [decimalFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
        [decimalFormatter setNumberStyle:NSNumberFormatterDecimalStyle];

        return decimalFormatter;
    }

从ObjectsHelper.m:

From ObjectsHelper.m:

- (NSNumberFormatter*)currencyFullFormatter {

    __ENTERING_METHOD__
    if (currencyFullFormatter != nil) {
        return currencyFullFormatter;
    }
    currencyFullFormatter = [[NSNumberFormatter alloc] init];
    [currencyFullFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
    [currencyFullFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];

    return currencyFullFormatter;
}

- (NSNumber*)currencyScale {

    __ENTERING_METHOD__
    if (currencyScale != nil) {
        return currencyScale;
    }
    self.currencyScale = [NSNumber numberWithInteger:[[[ObjectsHelper sharedManager] currencyFullFormatter] maximumFractionDigits]];

    return currencyScale;
}

编辑: 看起来这回答可能是在正确的轨道,只是不完全知道如何将在这里翻译。会改变

Seems like this answer might be on the right track, just not exactly sure how that would translate here. Would changing

    //get the cleaned price in the form of an integer - it has not yet been scaled
    NSInteger priceIntBeforeScale = [priceNumberBeforeScale integerValue];

    //scale the price for currency
    NSDecimalNumber *priceScaled = [NSDecimalNumber decimalNumberWithMantissa:priceIntBeforeScale exponent:(0-[[[ObjectsHelper sharedManager] currencyScale] integerValue]) isNegative:NO];

    //scale the price for currency
    NSDecimalNumber *priceScaled = [NSDecimalNumber decimalNumberWithMantissa:[priceNumberBeforeScale unsignedLongLongValue] exponent:(0-[[[ObjectsHelper sharedManager] currencyScale] integerValue]) isNegative:NO];

有可能解决这个问题?

推荐答案

好像有可能是一个问题的自定义键盘的iOS 8.需要进一步研究,但在这一点上至少出现了这个问题已经修复从设备中取出的自定义键盘。

Seems like there may be an issue with custom keyboards for iOS 8. Need to investigate further but at this point at least one occurrence of this issue has been fixed by removing the custom keyboard from the device.

编辑:难道证实这一具体问题是由一个iOS的8个自定义键盘的应用程序引起的。这个问题已经被报告给应用程序的发布者。

Is it confirmed that this particular issue was caused by an iOS 8 custom keyboard app. The issue has been reported to the publishers of the app.