iOS 应用程序在模拟器上运行正常,但在手机上崩溃。

3

我有以下代码:

var displayValue: Double{
    get{
        println("display.text =\(display.text!)")
        return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
    }
    set{
        display.text = "\(newValue)"
        userIsInTheMiddleOfTypingANumber = false;
    }
}

在模拟器上运行正常,但在手机上尝试时会崩溃。 这里是控制台输出:

digit= 3
display.text =3
operandStack =[3.0]
digit= 2
display.text =2
operandStack =[3.0, 2.0]
display.text =6.0
fatal error: unexpectedly found nil while unwrapping an Optional value

这一行代码:

NSNumberFormatter().numberFromString(display.text!)!

返回了 nil,导致应用崩溃,因为它无法解包可选项。我真的不知道出了什么问题。我正在按照 iTunes U 上的一些教程进行学习。

任何帮助都将不胜感激。


可能是因为 display.text 等于 nil,所以它才会混淆。 - Ashraf Tawfeeq
@AshrafTawfeeq 它并没有返回 nil,我打印了一下它的值是 6.0。 - Omar Al-Shammary
1个回答

8

尝试:

get{
    println("display.text =\(display.text!)")
    let formatter = NSNumberFormatter()
    formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
    return formatter.numberFromString(display.text!)!.doubleValue
}

由于默认情况下NSNumberFormatter使用设备的语言环境,所以小数分隔符可能不是"."。例如:
let formatter = NSNumberFormatter()
formatter.locale = NSLocale(localeIdentifier: "ar-SA")
print(formatter.decimalSeparator!) // -> outputs "٫"
formatter.numberFromString("6.0") // -> nil

使用这些区域设置的格式化程序无法解析像"6.0"这样的字符串。因此,如果您希望格式化程序得到一致的结果,应该明确指定区域设置。
至于en_US_POSIX区域设置,请参见文档

在大多数情况下,最好选择的区域设置是en_US_POSIX,它是专门设计为产生美国英语结果的区域设置,而不考虑用户和系统偏好。 en_US_POSIX还具有时间不变性(如果美国在未来某个时候更改日期格式方式,则en_US将更改以反映新行为,但en_US_POSIX不会),并且在平台之间保持一致(en_US_POSIX在iPhone OS上与在OS X上以及其他平台上的工作方式相同)。


那正是问题所在。不过有没有更好的解决方案?比如一劳永逸地设置区域设置? - Omar Al-Shammary
也许你想创建一个单例类或全局常量来保存缓存的格式化程序。但是,你应该知道 NSNumberFormatter 不是线程安全的。 - rintaro
哇,谢谢。这是一个微妙的错误... 只在别人的设备上发生,无法重现,等等。 - elsurudo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接