i unsure why/how works. have method use create nsmanagedobject subclasses:
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 }
as far can tell, both of these methods not return optional. insertnewobjectforentityforname returns anyobject, not anyobject?.
when call code, looks this:
let geocoder = clgeocoder() geocoder.geocodeaddressstring(string, completionhandler: { (placemarks, error) -> void in // check returned placemarks if let placemarks = placemarks placemarks.count > 0 { let topresult = placemarks[0] as! clplacemark let address = self.addressannotationlogic?.createwithplacemark(topresult) if address!.name.isempty { address!.name = string } } })
when call createwithplacemark, address
not optional. if tried adding !
end of line, compile error. makes sense me.
however, when try use address in if statement
if address!.name.isempty {
i required use force unwrap. why that? address variable not optional begin since createwithplacemark returns value, not optional.
the bang!
required because of optional chaining use in line:
let address = self.addressannotationlogic?.createwithplacemark(topresult)
when use optional chaining, if link in chain nil
, entire expression returns nil
, , whether or not result nil
, expression evaluates optional
value.
addressannotationlogic?
indicates addressannotationlogic
optional
of kind, means may nil
. if addressannotationlogic?
nil
, entire expression self.addressannotationlogic?.createwithplacemark(topresult)
evaluate nil
. if not nil
, address
still optional
value.
one suggestion use new if let
syntax unwrap of potential optional
values in code, this:
if let placemarks = placemarks placemarks.count > 0, let topresult = placemarks[0] as? clplacemark, let address = self.addressannotationlogic?.createwithplacemark(topresult) { if address.name.isempty { address.name = string } }
that substantially less produce runtime error. using !
risky.