2017-01-14 17 views
1

ジェネリックスでスウィフト3では以下のことができますか?スイフトのネストジェネリックス3

class BaseModel {} 
class Human : BaseModel { 
var name = "" 
} 

class BaseService<T: BaseVM<BaseModel>> { 
    //init viewmodel with generic model 
} 

class BaseVM<T: BaseModel> {} 

class HumanVM: BaseVM<Human> { 
var name = "" 
init(model : Human) { 
    super.init() 
    name = model.name 
    } 
} 

class HumanService: BaseService<HumanVM> {} 

私がやっていることは、baseServiceのジェネリックモデルでviewModelを初期化することです。

答えて

3

はい、ジェネリックをネストできます。あなたが持っているものに問題がこの行です:

ここ
class BaseService<T: BaseVM<BaseModel>> { ... 

あなたはBaseServiceは、その一般的なBaseModel IS BaseVMから継承する形で初期化されなければならないと述べました。あなたはBaseServiceは、そのモデルBaseModelから継承BaseVMから継承する形を取ることができるようにしたい場合は、あなたがこのようにそれを行う必要があるだろう。ここでは

class BaseService<T: BaseModel, U: BaseVM<T>> { ... 

はそれがコンパイルの上、あなたが持っているもののバージョンです。

class BaseModel {} 

class BaseVM<T: BaseModel> {} 

class BaseService<T: BaseModel, U: BaseVM<T>> { 
    //init viewmodel with generic model 
} 

class Human : BaseModel { 
    var name = "" 
} 

class HumanVM: BaseVM<Human> { 
    var name = "" 
    init(model : Human) { 
     super.init() 
     name = model.name 
    } 
} 

class HumanService: BaseService<Human, HumanVM> {} 

これらの関係を説明するもう1つの方法は、Protocols with AssociatedTypesを使用することです。あなたのコードは次のようになります:あなたは、私がより適切であると言うことはできません解決しようとしているのか、問題の詳細を知らなくても

protocol Model {} 

protocol BaseVM { 
    associatedtype VMModel : Model 
} 

protocol BaseService { 
    associatedtype ServiceVM : BaseVM 
} 

class Human : Model { 
    var name = "" 
} 

class HumanVM : BaseVM { 
    typealias VMModel = Human 
} 

class HumanService : BaseService { 
    typealias ServiceVM = HumanVM 
} 

EDITは、私はまだ、これはMVVMパターンに適用されるか、完全に明確でないんだけど、景色が関与している場合は、UIViewがそれに適合させることができるように、おそらく、あなたはProtocolベースのソリューションをしたいと思います。

+0

実際にMVVMパターンを適用しようとしていますが、モデルオブジェクトをカプセル化して、BaseServiceがサーバーにリクエストしてレスポンスを関連するモデルに変換し、関連するビューモデルをモデルオブジェクトで初期化します。 – user2628268

+0

編集を参照してください。特定の質問に関連する詳細をいくつか追加しました。私は、 'プロトコル'アプローチがおそらくもっと自然に適合するだろうと思います。 –