问题
I have a MapViewController for presenting annotations on map. It contains an object of type MapPresentable.
protocol MapPresentable {
associatedtype AnnotationElement: MKAnnotation
var annotations: [AnnotationElement] { get }
}
class MapViewController<M: MapPresentable>: UIViewController {
var mapPresentable: M!
}
MapViewController can also present route on map in case mapPresentable
conforms to RoutePresentable protocol.
protocol RoutePresentable: MapPresentable {
var getRouteLocations: [CLLocation] { get }
}
But when checking made inside MapViewController
if let routePresentable = mapPresentable as? RoutePresentable {
showRoute(routePresentable.getRouteLocations)
}
I got this Error:
Protocol 'RoutePresentable' can only be used as a generic constraint because it has Self or associated type requirements
回答1:
Updated
Sorry, I make mistakes. But there is no way to cast a protocol with associated type
.
Hope this will help.
As i known the routePresentable.getRouteLocations
has nothing to do with protocol MapPresentable
.
So you can divide RoutePresentable
to two protocol:
protocol MapPresentable {
associatedtype AnnotationElement: MKAnnotation
var annotations: [AnnotationElement] { get }
}
class MapViewController<M: MapPresentable>: UIViewController {
var mapPresentable: M!
}
protocol RoutePresentable: MapPresentable, CanGetRouteLocations {}
protocol CanGetRouteLocations {
var getRouteLocations: [CLLocation] { get }
}
if let routePresentable = mapPresentable as? CanGetRouteLocations {
showRoute(routePresentable.getRouteLocations)
}
Original
Because routePresentable.annotations
's Type is unprovided,
You can just remove associatedtype AnnotationElement: MKAnnotation
.
Or user generic struct instead:
struct MapPresentable<AnnotationElement: MKAnnotation> {
var annotations: [AnnotationElement] = []
}
struct RoutePresentable<AnnotationElement: MKAnnotation> {
var mapPresentable: MapPresentable<AnnotationElement>
var getRouteLocations: [CLLocation] = []
}
class MapViewController<AnnotationElement: MKAnnotation>: UIViewController {
var mapPresentable: MapPresentable<AnnotationElement>!
}
if let routePresentable = mapPresentable as? RoutePresentable<MKAnnotation> {
showRoute(routePresentable.getRouteLocations)
}
来源:https://stackoverflow.com/questions/40334856/protocol-can-only-be-used-as-a-generic-constraint