Search code examples
iosswiftxcodemapkitguard

Guard let is executing, but the code after it still works?


Ok, so I have a MapKit app, and just finished setting up the MKAnnotationView stuff. My MKAnnotationView class looks like this:

class JumpSpotAnnotationView: MKMarkerAnnotationView {

override var annotation: MKAnnotation? {
    willSet {
        // Extra safe, making sure there's no errors
        guard (newValue as? JumpSpotAnnotation) != nil else {
            print("The JumpSpotAnnotation or JumpSpotAnnotationView has something wrong if you are reading this. (JumpSpotAnnotationView)")
            return
        }
        // Setting up UI for the little Callout bubble that appears when you tap the annotation to see more info
        canShowCallout = true
        calloutOffset = CGPoint(x: 0, y: 0)
        rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
        //detailCalloutAccessoryView
        markerTintColor = .blue
    }
}
}

And my mapView viewFor function in my view controller looks like this:

extension ViewController: MKMapViewDelegate {

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    
    // Make sure the annotation entering the screen is a JumpSpotAnnotation, and exists
    guard let annotation = annotation as? JumpSpotAnnotation else {
        print("The JumpSpotAnnotation or JumpSpotAnnotationView has something wrong if you are reading this. (mapView viewFor func)")
        return nil
    }
    // Downcast the dequeued view as a JumpSpotAnnotationView, and make sure it has the same identifier as the registered JumpSpotAnnotationView above in viewDidLoad
    let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: "JumpSpotAnnotation") as? JumpSpotAnnotationView
    dequeuedView?.annotation = annotation
    // Return annotation views here
    return dequeuedView
}

}

Honestly, I put the guard let's in each of those, because I saw someone else do it that way and assumed it would be safer. I'm not really sure what their purpose is, other than making sure an annotation is actually entering the view, and is of the right type of annotation that I specified (I think it does that, at least).

Anyway, when I actually add the annotations by pressing a button in my app, everything works flawlessly, exactly as I want it to, but the print statements inside of the guard let's are showing up in the debugger. I have no idea what's causing them, nor any idea why my code is still working after they've triggered, when the fact that the guard let's have executed should stop the code below them from executing, and mess up my app. Can anyone offer ideas or explanations? I should add that the print statement from the mapView viewFor func appears once, as soon as the app loads up, then, the print statement from my JumpSpotAnnotationView appears each time I add an annotation.

I want to make sure I'm not missing some huge error that I'll regret down the line.


Solution

  • There are some MKAnnotations that are not the class of JumpSpotAnnotation when func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? works. It must be from MKMapView so dont worry about it. Your guard let works well.