2017-08-31 6 views
2

私はSwiftで汎用クラスをサブクラス化しようとしていますが、コンパイラが何を問題にしても、segfaultingを続けても問題はありません。汎用クラスをサブクラス化する

これは私がコンパイルするのにもっとも近いものですが、コンパイラが何らかの理由でTが何であるかを推測できないため、サブクラスのインスタンスを作成できません。

protocol GenericDataSourceCellProtocol { 
    associatedtype ModelType 
    var model: ModelType? {get set} 
} 

struct MyCellState {} 

class MyCell: UITableViewCell, GenericDataSourceCellProtocol { 
    var model: MyCellState? 
} 

class Generic2DDataSource<U, T> 
where U:GenericDataSourceCellProtocol, U:UITableViewCell, T == U.ModelType { 

    let items: [[T]] 
    init (items: [[T]]) { 
     self.items = items 
    } 
} 


class SubclassedDataSource: Generic2DDataSource<MyCell, MyCellState> {} 

let state = MyCellState() 
let items = [[state]] 
let datasource = SubclassedDataSource(items: items) 
// cannot convert value of type '[Array<MyCellState>]' to expected argument type '[[T]]' 

この方法を使用する方法はありますか?私は何が欠けていますか?

答えて

1

ここでは、非常に重要ではないスウィフトタイプのシステムのものがたくさんあります。しかし、これはあなたが進めていることですか?

protocol GenericDataSourceCellProtocol { 
    associatedtype ModelType 

    var model: ModelType? {get set} 
} 

struct MyCellState {} 

class MyCell: UITableViewCell, GenericDataSourceCellProtocol { 

    typealias ModelType = MyCellState 

    var model: MyCellState? 
} 

class Generic2DDataSource<U> where U: GenericDataSourceCellProtocol, U: UITableViewCell { 

    typealias T = U.ModelType 

    let items: [[T]] 

    init(items: [[T]]) { 
     self.items = items 
    } 
} 


class SubclassedDataSource: Generic2DDataSource<MyCell> { 

} 

let state = MyCellState() 
let items = [[state]] 
let datasource = SubclassedDataSource(items: items) 

そして、私は私がこれまでにコードを変更した場合、それはエラーが離れて行くようになりますことを見出したので、何を持っていることは技術的に有効であるべきだと思う:私は機能thingを追加

protocol GenericDataSourceCellProtocol { 
    associatedtype ModelType 

    var model: ModelType? {get set} 
} 

struct MyCellState {} 

class MyCell: UITableViewCell, GenericDataSourceCellProtocol { 

    typealias ModelType = MyCellState 

    var model: ModelType? 
} 

class Generic2DDataSource<U, T> where U: GenericDataSourceCellProtocol, U: UITableViewCell, T == U.ModelType { 

    let items: [Array<U.ModelType>] 

    init(items: [Array<U.ModelType>]) { 
     self.items = items 
    } 

    func thing() -> T { 
     let value = items[0][0] 

     return value 
    } 
} 

class SubclassedDataSource: Generic2DDataSource<MyCell, MyCellState> { 
} 

お知らせベースクラスに追加します。 Xcodeでは、変数valueをオプション+クリックすることができ、コンパイラがどのタイプのものであるかを知ることができます。この場合、items[Array<U.ModelType>]と指定しても、valueのタイプはTです。彼らはT == U.ModelTypeのために同じでなければなりませんが、何らかの理由でコンパイルのサブクラス化中にそれを理解できません。

あなたはUとTの間の関係を形成しているので、Tは本当に必要ではないと思います。私の最初のコードブロックのように、汎用パラメータとしてUを提供するだけで十分です。

+0

偉大な答えであり、間違いなく問題を解決しました、ありがとう!私は、他の誰かが私の元の例でコンパイラの動作についての説明を思い付くことができるかどうかを知りたいので、あなたの答えを受け入れる前に数日待つことになります。もう一度ありがとう、私はそれを調べる時間を割いていただきありがとうございます! – Rog

+0

私も興味があります。 –

+1

@Rog私はあなたのコードをXcode 9b6に入れてコンパイルして完全に動いたので、修正されたコンパイラのバグのようです。 –

関連する問題