2017-09-03 7 views
1

別のプロトコルの汎用機能で確認プロトコルを提供できますか? 私はそれをこのように動作させようとしましたが、それは不可能です、または私はいくつかの間違いを犯しました。associatedtypeのプロトコル汎用機能のプロトコル

マイコード:

protocol DataModelProtocol { 
    associatedtype ObjectProtocol: Protocol 
    func fetchObjects<T: ObjectProtocol>() -> [T]? 
    func fetch<T: ObjectProtocol>(object: T) -> T? 
    func delete<T: ObjectProtocol>(allObjectOf type: T.Type) 
    func insert<T: ObjectProtocol>(_ object: T) 
    func save<T: ObjectProtocol>(_ object: T) 
    func update<T: ObjectProtocol>(_ object: T) 
    func delete<T: ObjectProtocol>(_ object: T) 
} 

エラーメッセージ:

非プロトコル、非クラスタイプ 'Self.ObjectProtocol' から継承

Image of Xcode error

それは、このようにしか動作しませんが、より柔軟にしたいと考えています:

protocol DataModelProtocol { 
    typealias ObjectProtocol = NSManagedObject 
    ... 
} 

答えて

1

これはおそらくだろう戻り値の型をオブジェクトクラス自体に与えた方が簡単です。

あなたは2つのプロトコルが必要になりますが、それはプロトコルとジェネリック医薬品を混合避けるだろう:

// The first protocol is for the base class of data objects 
protocol DataProtocol 
{} 

// The protocol provides the "typed" equivalents of the model's 
// data manipulation methods. 
// By using an extension to DataProtocol, this only needs to 
// be done once for all models and data objects. 
extension DataProtocol 
{ 
    static func fetchObjects(from model:DataModelProtocol) -> [Self]? 
    { return model.fetchObjects(object: Self.self) as! [Self]? } 

    static func fetch(from model:DataModelProtocol) -> Self? 
    { return model.fetch(object: Self.self) as! Self? } 

    // ... 
} 

// The second protocol is for the data models 
// It requires implementation of the data manipulation methods 
// using the general "DataProtocol" rather than any specific class 
// The actual instances it produces must be of the appropriate class 
// however because they will be type casted by the DataProtocol's 
// default methods 
protocol DataModelProtocol 
{ 
    func fetchObjects(object:DataProtocol.Type) -> [DataProtocol]? 
    func fetch(object:DataProtocol.Type) -> DataProtocol? 
    // ... and so on 
} 

...ここ は、プロトコルがどのように使用できるかの簡単な(ナイーブ)の例です。あなたから始まることになるので、あなたのアプローチとは少し違うだろうなプロトコルを使用して...

// The base class (or each one) can be assigned the DataProtocol 
// (it doesn't add any requirement) 

class LibraryObject : DataProtocol 
{} 

class Author: LibraryObject 
{ 
    var name = "" 
} 

class Book: LibraryObject 
{ 
    var title = "" 
} 

// This is a simple class that implements a DataModelProtocol 
// in a naive (and non-core-data way) 

struct LibraryModel:DataModelProtocol 
{ 
    var authors:[Author] = [ Author(), Author() ] 

    var books:[Book] = [ Book(), Book(), Book(), Book(), Book() ] 

    func fetchObjects(object: DataProtocol.Type) -> [DataProtocol]? 
    { 
    return object == Book.self ? books 
      : object == Author.self ? authors 
      : nil 
    } 

    func fetch(object:DataProtocol.Type) -> DataProtocol? 
    { return nil } 

} 

... を(私は意図的にソリューションの一般性を示すために、コアデータを使用しないことを選びました)むしろモデル にパラメータとして渡すよりもオブジェクトクラス...

var library = LibraryModel() 
let allBooks = Book.fetchObjects(from:library) // this almost reads like english 
0

あなたが別のプロトコルの一般的な機能を適合させたい場合は、単に、余分なObjectProtocolを作るための必要性を全くプロトコルに準拠しTassociatedTypeを作成していない:

​​
+0

私はこのようになります場合は、それは私が親と子供、との仕事をフェッチ機能するようにしたい例えば1種類 でのみ動作しますましたNSManagedObjectのサブクラスです Buこのソリューションでは、私はいつもNSManagedObjectを取得します –

+0

@ YerkebulanAbildinなぜですか? – paper1111

関連する問題