关于Swift的可选问题

时间:2014-08-21 08:38:46

标签: ios exception swift

我是Swift的新手。

我正在努力学习基础知识和结构。我已经开始了一个项目,我正在学习我的进步。

fatal error: unexpectedly found nil while unwrapping an Optional value

我在编码时将上述例外情况考虑在内。

虽然我已阅读Apple文档,但我的想法并不清楚。

有没有人可以讲述这个例外及其原因的故事,如何与Swift上的Optional相关?

由于

代码如下

var globalDaily:Float = 0.0

for var i=0; i<favoritesArray.count; ++i {

    var tempDict:NSMutableDictionary = favoritesArray.objectAtIndex(i) as NSMutableDictionary
    let tempFloat:Float! = tempDict.objectForKey("amount") as? Float

    globalDaily = globalDaily + tempFloat//This line gives the bad access

}

2 个答案:

答案 0 :(得分:1)

我认为只有当Float具有Dictionary类型

时,您才可以使用向下广播AnyObject

参见示例:

var globalDaily:Float = 0.0

var favoritesArray:Array<Dictionary<String,AnyObject>> = []

var item:Dictionary<String,AnyObject> = ["amount": 2.0]
favoritesArray.append(item)

for var i=0; i<favoritesArray.count; ++i{

    var tempDict:Dictionary = favoritesArray[i]

    if let tempFloat:Float = tempDict["amount"] as AnyObject! as  Float!{
        globalDaily = globalDaily + tempFloat // output 2
    }
    else{
        globalDaily = globalDaily + 5
    }

但如果key不存在,我们会5

因此,如果您知道自己只有Float类型,则只需编写:

var globalDaily:Float = 0.0

var favoritesArray:Array<Dictionary<String,Float>> = []

var item:Dictionary<String,Float> = ["amount": 2.0]
favoritesArray.append(item)

for var i=0; i<favoritesArray.count; ++i{

    var tempDict:Dictionary = favoritesArray[i]

    if let tempFloat:Float = tempDict["amount"]{
        globalDaily = globalDaily + tempFloat
    }
    else{
        globalDaily = globalDaily + 5
    }

答案 1 :(得分:1)

在swift中,变量必须始终包含有效值。对于值类型(int,float,strings,structs等),它意味着必须初始化变量。对于引用类型(类的实例),它们必须初始化为类的有效实例,而不能是nil

在swift中,变量不能保持未初始化状态。但有些情况下,允许变量未使用nil进行初始化或初始化。这就是为什么引入选项的概念的原因。可选变量可以包含其数据类型的有效值,或者为nil。通过将问号后缀为类型来声明可选变量,例如:var x = Int?

建议阅读: Swift编程语言一书中的Optionals

至于你的问题,请点击这里:

let tempFloat:Float! = tempDict.objectForKey("amount") as? Float

您从字典中读取了一个值,如果没有为nil键设置值,则可以为amount。这就是为什么有一个演员as? Float。转换为可选类型,可以包含有效的Float类型或nil。

在作业let tempFloat:Float!的左侧,您声明右侧不是nil(使用感叹号),并且您可以使用tempFloat而不展开它。

如果字典包含amount键的有效浮点数,那么这不是问题。但是如果字典不包含值,那么当您尝试使用tempFloat变量时,会尝试将nil转换为Float,这会导致异常。

解决方法如下所示:

let tempFloat = tempDict.objectForKey("amount") as? Float

if let unwrappedFloat = tempFloat {
    globalDaily = globalDaily + unwrappedFloat
}

这确保只有当tempFloat包含有效的浮点值时才使用变量(并执行加法)。