选择swift,需要未包装

选择swift,需要未包装,swift,Swift,我不确定这是为什么/如何工作的。我有一个创建NSManagedObject子类的方法: public func createWithPlacemark(placemark: CLPlacemark) -> AddressAnnotation { let entity = NSEntityDescription.insertNewObjectForEntityForName("AddressAnnotation", inManagedObjectContext: manage

我不确定这是为什么/如何工作的。我有一个创建NSManagedObject子类的方法:

public func createWithPlacemark(placemark: CLPlacemark) -> AddressAnnotation {
        let entity = NSEntityDescription.insertNewObjectForEntityForName("AddressAnnotation", inManagedObjectContext: managedObjectContext) as! AddressAnnotation

        return updateAnnotation(entity, withPlacemark: placemark)
    }

    public func updateAnnotation(annotation: AddressAnnotation, withPlacemark placemark: CLPlacemark) -> AddressAnnotation {
        annotation.address = placemark.subThoroughfare
        annotation.street = placemark.thoroughfare
        annotation.city = placemark.locality
        annotation.state = placemark.administrativeArea
        annotation.zip = placemark.postalCode

        if !placemark.name.isEmpty {
            annotation.name = placemark.name
        }
        else if placemark.areasOfInterest[0] as? String != nil{
            annotation.name = placemark.areasOfInterest[0] as! String
        }
        else {
            annotation.name = ""
        }

        annotation.latitude = placemark.location.coordinate.latitude
        annotation.longitude = placemark.location.coordinate.longitude

        return annotation
    }
据我所知,这两种方法都不会返回可选的。insertNewObjectForEntityForName返回AnyObject,而不是AnyObject

当我调用此代码时,它如下所示:

let geocoder = CLGeocoder()
            geocoder.geocodeAddressString(string, completionHandler: {
                (placemarks, error) -> Void in

                // Check for returned placemarks
                if let placemarks = placemarks where placemarks.count > 0 {
                    let topResult = placemarks[0] as! CLPlacemark

                    let address = self.addressAnnotationLogic?.createWithPlacemark(topResult)


                    if address!.name.isEmpty {
                        address!.name = string
                    }


                }
            })
if let placemarks = placemarks where placemarks.count > 0,
   let topResult = placemarks[0] as? CLPlacemark,
   let address = self.addressAnnotationLogic?.createWithPlacemark(topResult) {
       if address.name.isEmpty {
           address.name = string
       }
}
当我调用createWithPlacemark时,地址不是可选的。如果我尝试添加一个!在这行的末尾,我得到了一个编译错误。这对我来说是有道理的

但是,当我尝试在if语句中使用地址时

if address!.name.isEmpty {
我需要使用原力展开。为什么呢?address变量开头不是可选的,因为createWithPlacemark返回一个值,而不是可选的。

砰!是必需的,因为您在此行中使用:

let address = self.addressAnnotationLogic?.createWithPlacemark(topResult)
使用可选链接时,如果链中的任何链接为nil,则整个表达式返回nil,并且无论结果是否为nil,表达式的计算结果始终为可选值

地址注释逻辑?指示addressAnnotationLogic是某种可选的,这意味着它可能为零。如果是地址注释逻辑?如果为nil,则整个表达式self.addressAnnotationLogic?.createWithPlacemarktopResult的计算结果将为nil。如果不是nil,address仍然是可选值

一个建议是使用新的if-let语法来展开代码中所有潜在的可选值,如下所示:

let geocoder = CLGeocoder()
            geocoder.geocodeAddressString(string, completionHandler: {
                (placemarks, error) -> Void in

                // Check for returned placemarks
                if let placemarks = placemarks where placemarks.count > 0 {
                    let topResult = placemarks[0] as! CLPlacemark

                    let address = self.addressAnnotationLogic?.createWithPlacemark(topResult)


                    if address!.name.isEmpty {
                        address!.name = string
                    }


                }
            })
if let placemarks = placemarks where placemarks.count > 0,
   let topResult = placemarks[0] as? CLPlacemark,
   let address = self.addressAnnotationLogic?.createWithPlacemark(topResult) {
       if address.name.isEmpty {
           address.name = string
       }
}
这将大大降低产生运行时错误的可能性。使用!是有风险的。

她说地址不是可选的,但我想知道这怎么可能,因为她使用可选链接来表示地址地址是可选的,不管她是否知道:她患有可选拒绝综合症。©2015莱瓦戈