0

我正在尝试制作一个标签来显示温度,超过 100 的温度最多使用 3 位数字,但我不想要任何小数...

    NSString *longtempstring = [tmp description];
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    [formatter setMaximumFractionDigits:3];
    [formatter setMinimumFractionDigits:0];
    NSString *shorttempstring = [formatter stringForObjectValue:[NSString  stringWithString:longtempstring]];

上面的代码总是返回 (null)

有任何想法吗?

4

3 回答 3

1

你得到nil是因为你传递给的对象stringForObjectValue:不是预期的类型。

首先,不要使用stringForObjectValue:. 那是父类的成员,NSFormatter. NSNumberFormatter具有更具体的方法,可以避免混淆对象类型,如numberFromString:stringFromNumber:

其次,NSNumberFormatter用于从数字到格式化字符串或格式化字符串到数字。不是直接从格式化字符串到格式化字符串。您将需要使用一个数字格式化程序来读取您的原​​始字符串并生成一个数字,另一个从该数字生成一个新的更短的格式化字符串。

当然,您可以通过使用NSScanner或获取长字符串的子字符串(删除除数字本身之外的所有内容)然后使用NSString方法integerValuedoubleValue. 也可以使用正则表达式从第一个(较长的)字符串中提取数字。

总而言之,这是一个两步过程。第一步(获取数字)可以通过多种方式完成,并且NSNumberFormatter可能不是最简单的方法。第二步(获得一个新的较短的字符串)是NSNumberFormatter完美的。

于 2013-02-07T22:55:33.593 回答
0

我通过将 NSString 转换为 NSNumber 并仅从字符串中提取整数值来修复它,从而删除任何小数。

        NSString *longtempstring = [tmp description];
        NSNumber *tempintegervalue = [NSNumber numberWithInteger:[longtempstring integerValue]];
        NSString *shorttempstring = [tempintegervalue stringValue];
于 2013-02-07T23:00:02.343 回答
0
NSString *longtempstring = [tmp description];

What is the value of longtempstring here? Is it even a number?

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:3];
[formatter setMinimumFractionDigits:0];

Why do you set maximum fraction digits to 3 if you say that you don't want any fraction digits? Fraction digits are what is "after the dot" and you say you don't want any decimals. If you don't want any decimals, minimum and maximum must be set to 0.

NSString *shorttempstring = [formatter stringForObjectValue:[NSString  stringWithString:longtempstring]];

First of all, why are you copying the string? [NSString stringWithString:...] creates a new string that is a copy of the string you provide as argument. Strings are immutable, there is no need to copy them, they won't be modified. If you are afraid that a NSString may in fact be a NSMutableString, after all that is a subclass of NSString and you want to copy it, just copy it by calling [aString copy]. copy is a very smart method here. If the NSString is in fact a mutable string, it will really copy it, so you get an immutable copy. If it is not a mutable string, though, copy just returns the same string with a retain count increased by one (so in that case copy behaves exactly like retain). However, in your case copying makes no sense whatsoever.

And second, what makes you believe, that you can feed a string into a NSNumberFormater? It is called NSNumberFormater because it formats objects of type NSNumber. How is a NSString a NSNumber? It is not called NSStringFormater. If you feed an object of the wrong class to a formater, it will return nil, that's how this method is documented.

If your longtempstring contains a number with fraction, e.g. 12.345, then the correct code would look like this:

NSString * longtempstring = [tmp description];
NSNumberFormatter * formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:0];
[formatter setMinimumFractionDigits:0];
NSNumber * tempnumber = [NSNumber numberWithDouble:[longtempstring doubleValue]];
NSString * shorttempstring = [formatter stringForObjectValue:tempnumber];

However, if all you want to do is cut off the decimals, that is a horrible way to do it. This can be done much more effective:

double d;
NSString * longtempstring;
NSString * shorttempstring;

longtempstring = @"12.345";
d = [longtempstring doubleValue];
shorttempstring = [NSString stringWithFormat:@"%d", (int)d];

This is much shorter, needs less memory, and is at least three times faster. If you want to round the number (that means everything with a fraction .5 and above is rounded to the next higher value), just round it:

d = round([longtempstring doubleValue]);
于 2013-02-07T23:02:44.293 回答