2016-10-30 11 views
4

マップに注釈を表示するためのMapViewControllerがあります。これにはMapPresentable型の オブジェクトが含まれています。プロトコルは一般的な制約としてのみ使用できます

protocol MapPresentable { 
    associatedtype AnnotationElement: MKAnnotation 
    var annotations: [AnnotationElement] { get } 
} 

class MapViewController<M: MapPresentable>: UIViewController { 
    var mapPresentable: M! 
} 

MapViewControllerも場合mapPresentableに地図上に存在するルートはRoutePresentableプロトコルに準拠することができます。

protocol RoutePresentable: MapPresentable { 
    var getRouteLocations: [CLLocation] { get } 
} 

しかしMapViewController

if let routePresentable = mapPresentable as? RoutePresentable { 
    showRoute(routePresentable.getRouteLocations) 
} 

内部で作られたチェックするとき、私はこのエラーを得た:

Protocol 'RoutePresentable' can only be used as a generic constraint because it has Self or associated type requirements 

答えて

4

を更新しました申し訳ありませんが、私は間違いを犯します。しかし、associated typeでプロトコルをキャストする方法はありません。

希望すると、これが役立ちます。

私が知っているように、routePresentable.getRouteLocationsはプロトコルMapPresentableとは関係ありません。

だから2つのプロトコルにRoutePresentableを分割することができます

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) 
} 

はオリジナル

routePresentable.annotationsのタイプがunprovidedあるので

あなただけassociatedtype AnnotationElement: MKAnnotationを削除することができます。

またはその代わりに、ユーザーの一般的な構造体:

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) 
} 
+0

は、あなたの答えをありがとう!残念ながら、私はあなたにジェネリックソリューションを理解していませんでした。 MapPresentable&RoutePresentableはプロトコルでなければなりません(実際のタイプに準拠しています)。どのように正確にキャストステートメントが動作するのでしょうか?この場合、MapPresentableとRoutePresentableは異なる構造体です。 – GeRyCh

+0

素晴らしい!あなたのアップデートはキャストの問題を解決するのに役立ちました。ありがとうございました! – GeRyCh