展开一个nil的Optional值

时间:2015-06-23 23:38:41

标签: ios iphone swift

我遇到一个涉及选项的常见错误,我有一个NSUserDefault值,这是使用位置管理器功能的用户位置:

func locationManager(manager: CLLocationManager!,
    didUpdateLocations locations: [AnyObject]!)
{

    //First Convert it to NSNumber.
    let lat : NSNumber = NSNumber(double: latestLocation.coordinate.latitude)
    let lng : NSNumber = NSNumber(double: latestLocation.coordinate.longitude)

    //Store it into Dictionary
    let locationDict = ["lat": lat, "lng": lng]

    //Store that Dictionary into NSUserDefaults
    NSUserDefaults.standardUserDefaults().setObject(locationDict, forKey: "Location")
}

当我运行我的应用时,它在我的viewDidLoad()方法中的以下代码块上的let userLoc = NSUserDefaults行崩溃了。

    let userLoc = NSUserDefaults.standardUserDefaults().objectForKey("Location") as! [String : NSNumber]

    //Grab location from that Dictionary (from func LocationManager below)
    let userLat = userLoc["lat"]
    let userLng = userLoc["lng"]

    //declare MKPointAnnotation()
    var Annotation = MKPointAnnotation()
    //Convert NSNumber to CLLocationDegrees
    Annotation.coordinate.latitude = userLat as! CLLocationDegrees
    Annotation.coordinate.longitude = userLng as! CLLocationDegrees

错误是:

fatal error: unexpectedly found nil while unwrapping an Optional value.

我怀疑这是因为我没有存储变量

NSUserDefaults.standardUserDefaults().objectForKey("Location") 

直到viewDidLoad方法运行。

如何避免此错误? 我应该在我的视图中运行locationManager()函数吗?
我试过它有一个错误...

任何帮助都会非常感激。我被困在这几个小时。

约什

3 个答案:

答案 0 :(得分:4)

使用'!'时需要小心打开可选项或转换值。这说“我知道这不是nil /这个类的一个实例,如果不是,那就糟糕了,抛出异常”。 如果它有可能是nil /不是所需类的实例,那么你应该使用'?'并适当地对结果采取行动。 如果让userLoc = NSUserDefaults.standardUserDefaults()。objectForKey(“Location”)为? [String:NSNumber] {     //从该词典中抓取位置(从下面的func LocationManager)     让userLat = userLoc [“lat”]     让userLng = userLoc [“lng”]     //声明MKPointAnnotation()     var Annotation = MKPointAnnotation()     //将NSNumber转换为CLLocationDegrees     Annotation.coordinate.latitude = userLat as! CLLocationDegrees     Annotation.coordinate.longitude = userLng as! CLLocationDegrees } 你第二次使用'!' - 当您为坐标分配纬度/经度时是正确的 - 如果转换不成功,那么您存储的数据有问题,崩溃可能是一种合理的方法,因此您可以进行调试。 如果数据来自某些外部来源并且可能无效则使用'?'某种错误处理仍然是更好的方法。

答案 1 :(得分:2)

如果你不确定它是否仍然if那么用nil语句包裹它怎么样?

if let userLoc = NSUserDefaults.standardUserDefaults().objectForKey("Location") as? [String : NSNumber] {

    //Grab location from that Dictionary (from func LocationManager below)
    let userLat = userLoc["lat"]
    let userLng = userLoc["lng"]

    //declare MKPointAnnotation()
    var Annotation = MKPointAnnotation()
    //Convert NSNumber to CLLocationDegrees
    Annotation.coordinate.latitude = userLat as! CLLocationDegrees
    Annotation.coordinate.longitude = userLng as! CLLocationDegrees
}

如果您确定当时不应该nil(viewDidLoad :),您可能需要向我们提供更多代码,以便我们帮您确定哪里出错。

请记住,在打开包装之前一定要确保它不是nil,否则请不要使用!

答案 2 :(得分:-2)

您必须检查在您尝试强制转换为Double的字符串中是否使用let latitude : CLLocationDegrees = Double("9,123")! 而不是let latitude : CLLocationDegrees = Double("9.123")!

这个抛出零错误:

if x == (1 or 2):

这是正确的方法:

if x == 1 or x == 2: