NSNumberFormatter:dispatch_once 货币变化的地方

NSNumberFormatter: dispatch_once where Currency changes

我有一个表格视图,其中 NSDecimalNumber 的列表将以他们自己的货币显示。

我在 NSNumberFormatter 上使用 dispatch_once 但请注意,有时它会完全忽略我设置小数位数或小数位数后缀的命令。

目前我能够解决这个问题的唯一方法是初始化 NSNumberFormatter 每一行,这有点傻。

即:

- (NSNumberFormatter *)currencyFormatWithCurrency:(NSString *)currency
{
    static NSNumberFormatter *_formatter = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _formatter = [[NSNumberFormatter alloc] init];
    });

    [_formatter setCurrencyCode:currency];
    [_formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    [_formatter setMaximumFractionDigits:0];
    [_formatter setGeneratesDecimalNumbers:NO];
    [_formatter setRoundingMode:NSNumberFormatterRoundUp];

    return _formatter;
}

// someCurrency is a string that will change per row
// someAmount is a NSDecimalNumber that will change per row
  NSNumberFormatter *formatter = [self currencyFormatWithCurrency:someCurrency];
    NSString *formattedAmount = [formatter stringFromNumber:someAmount];

    self.amountLabel.text = formattedAmount;

有时,如果我输入 80000 这样的数字,它会 return 80,000.00(有时取决于货币)。

我想我可以初始化 NSNumberFormatter 并在每一行上将其置零。

也许我做错了,但是否有办法确保我不需要继续创建 NSNumberFormatter 来确保它理解我给它的规则?

非常感谢

NSNumberFormatter 不是线程安全的。那会导致各种各样的问题。 (好吧,你使用它的方式并不是真正的线程安全,因为你可能在一个线程中修改它,而另一个线程正在使用它,但是仅从两个线程使用 NSNumberFormatter 是不安全的)。

你总是可以用

这样的方法做一些事情
NSString* lastCurrency = nil;
NSNumberFormatter* formatter = nil; 

for (;;) {
    ...
    NSString* currency = ...;
    if (! [lastCurrency isEqualToString:currency]) {
        lastCurrency = currency; 
        formatter = ...;
    }
}

如果在大多数情况下货币不变,则效果很好。

我认为这是我从以下内容中得到的一个可能的解决方案 website 可能会有所帮助。

NSString *HTCurrencyString(double amount, NSString *currencyCode)
{
    static NSString *currencyFormatterKey = @"HTCurrencyFormatter";
    NSNumberFormatter *currencyFormatter = [[NSThread currentThread] threadDictionary][currencyFormatterKey];
    if (currencyFormatter == nil)
    {
        currencyFormatter = [[NSNumberFormatter alloc] init];
        [currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
        [currencyFormatter setLocale:[NSLocale currentLocale]];

        [[NSThread currentThread] threadDictionary][currencyFormatterKey] = currencyFormatter;
    }
    [currencyFormatter setCurrencyCode:currencyCode];
    [currencyFormatter setMaximumFractionDigits:0];
    [currencyFormatter setRoundingMode:NSNumberFormatterRoundHalfUp];
    return [currencyFormatter stringFromNumber:@(amount)];
}