在Swift中,可以将另一个对象的函数转换为不同类型的对象吗?

在Swift中,可以将另一个对象的函数转换为不同类型的对象吗?,swift,casting,Swift,Casting,我正在关注Ray Wenderlich的MapKit教程,我对几行代码的内容有点困惑 特别是在注释//4下,似乎开发人员使用了一个常量变量,该变量等于mapView的函数,然后将其强制转换为MKMarkAnnotationView类型 //4 if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView {

我正在关注Ray Wenderlich的MapKit教程,我对几行代码的内容有点困惑

特别是在注释//4下,似乎开发人员使用了一个常量变量,该变量等于mapView的函数,然后将其强制转换为MKMarkAnnotationView类型

//4
        if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView {
            dequeuedView.annotation = annotation
            view = dequeuedView
        }
我从未见过这样的事情,但我想在继续之前了解一下。我知道函数也是对象,我知道可以将函数放在变量中,但是在本例中,开发人员不仅将函数放在变量中,而且还将其转换为另一种类型,这很容易混淆。这行代码可以分解成更小的步骤来帮助我更好地理解它吗

似乎开发人员调用了mapView对象,该对象的类型为MKMapView,但被允许选择性地将其强制转换为mkMarkerNotationView类型

//4
        if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView {
            dequeuedView.annotation = annotation
            view = dequeuedView
        }
以下是viewController的完整代码(如果需要):

import UIKit
import MapKit

class ViewController: UIViewController {

    //created an IBOutlet to control the mapView in interface builder
    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
    super.viewDidLoad()

        //initial location to zoom the map into once the app is opened.
        let initialLocation = CLLocation.init(latitude: 21.282778, longitude: -157.829444)

        centerMapOnLocation(location: initialLocation)

        mapView.delegate = self

        let artwork = Artwork.init(title: "King David Kalakaua", locationName: "Waikiki Gateway Park", discipline: "Sculpture", coordinate: CLLocationCoordinate2D.init(latitude: 21.283921, longitude: -157.831661))

        mapView.addAnnotation(artwork)

  }

    //when specifying a latlong to zoom into in iOS, you must also state a rectangular region for it to display a correct zoom level???
    let regionRadius: CLLocationDistance = 1000

    func centerMapOnLocation(location: CLLocation){
        let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius, regionRadius)
        mapView.setRegion(coordinateRegion, animated: true)
    }

}

extension ViewController: MKMapViewDelegate {

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        //2
        guard let annotation = annotation as? Artwork else {
            return nil
        }
        //3
        let identifier = "marker"
        var view: MKMarkerAnnotationView
        //4
        if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView {
            dequeuedView.annotation = annotation
            view = dequeuedView
        } else {
            //5
            view = MKMarkerAnnotationView.init(annotation: annotation, reuseIdentifier: identifier)
            view.canShowCallout = true
            view.calloutOffset = CGPoint.init(x: -5, y: 5)
            view.rightCalloutAccessoryView = UIButton.init(type: .detailDisclosure)
            view.markerTintColor = UIColor.green
        }
        return view
    }
}

这是可选的展开。
正如您所注意到的-developer可以选择将函数的结果强制转换为
mkmarkernotationview
。但他也使用了
if let
语法,这是可选的展开。这意味着该代码

dequeuedView.annotation = annotation
view = dequeuedView
仅在强制转换成功时执行(即,如果强制转换结果不是
nil
)。否则,此代码将被忽略

您也可以使用
guard
语句执行此操作。例如:

guard let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView 
else { // code here will be executed if casting fails. In this case you also have to return function }

dequeuedView.annotation = annotation
view = dequeuedView

更多信息

您可能想了解可选强制转换(
as?
)和可选绑定(
如果让
)您是对的,我完全忘记了作为开发人员如何将函数的结果强制转换为其他类型!MkmarkerNotationView继承自UIView,类似于MapView!非常感谢。