2016-03-28 15 views
3

に準拠して、同じ型のオブジェクトを返すか、私は今、私はクラスがプロトコルに準拠しているものは何でもその関数の戻り値を作成しようとしている以下のプロトコル迅速で、どのように私は、プロトコル

protocol JSONInitializable { 
    static func initialize(fromJSON: NSDictionary) throws -> Self? 
} 

を持っています。私。プロトコルに準拠したクラスFooを持っていれば、メソッドからFooオブジェクトを返したいと思います。これどうやってするの?

extension Foo: JSONInitializable { 
    static func initialize(fromJSON: NSDictionary) throws -> Foo? { 
    } 
} 

私はエラーを取得する:

Method 'initialize' in non-final class 'Foo' must return 'Self' to conform to protocol 'JSONInitializable'

答えて

3

オートコンプリートがお手伝いしますが、Fooがクラスであれば基本的に、あなたは自分のプロトコルで方法の正確なシグネチャと一致する方法が必要になります。ここでの注意点としては

class Foo {} 

protocol JSONInitializable { 
    static func initialize(fromJSON: [String : AnyObject]) throws -> Self? 
} 

extension Foo: JSONInitializable { 
    static func initialize(fromJSON: [String : AnyObject]) throws -> Self? { 
     return nil 
    } 
} 

、あなたは、このメソッド内で、のすべてのインスタンスを交換する必要があります210はSelfである。コンストラクターを使用する場合は、必要に応じてマークされたコンストラクターにする必要があります。

これを念頭に置いて、という静的メソッドではなく、イニシャライザが必要な場合は、Blake Lockley's answerを参照してください。しかし、この答えは、Selfをどのように扱うかという問題に答えることを意味します。Selfが初期化子ではないメソッドを必要とする場合があるからです。


Fooがクラスでない場合、それはサブクラスすることはできません値の型であり、そのようなものとして、私たちは型の名前を返す:

struct Foo: JSONInitializable { 
    static func initialize(fromJSON: [String : AnyObject]) throws -> Foo? { 
     return nil 
    } 
} 
enum Foo: JSONInitializable { 
    case One, Two, Three 

    static func initialize(fromJSON: [String : AnyObject]) throws -> Foo? { 
     return nil 
    } 
} 

Self?をクラスのメソッドから返す必要があるのは、継承のためです。プロトコルは、それに準拠すれば、initializeと呼ばれるメソッドを持ち、その戻り値の型はあなたの任意のバージョンであることを宣言します。

我々はFoo年代initializeメソッドを記述する場合、あなたがそれを書いたように、我々はBarFooをサブクラス化した場合、その後、その後、今、私たちは私たちのプロトコルに準拠し壊れています。 Barは、Fooからプロトコルへの適合を継承しましたが、initializeと呼ばれ、Bar?を返すメソッドはありません。それはFooを返すものを持っています。

ここでSelfを使用すると、私たちのサブクラスがこのメソッドを継承するときには、どんな型でも返すことになります。 SelfはスウィフトのObjective-C's instancetypeに相当します。

+0

だからこれは私がメソッドからFoo' '型のオブジェクトを返してみましょうでしょうか? – smac89

+0

'Foo'のインスタンスで呼び出すと' Foo'を返します。 'Foo'をサブクラス化して' class Bar:Foo'を作ると 'Bar'を返します。 – nhgrif

+0

私はこれを試しましたが、メソッドから 'Foo'型のオブジェクトを返そうとするとエラーになります。 'Foo'型の式を 'Self'型に変換できないと言っています。xcode 7.3を使用しています。 – smac89

1

nhgrifに記載されているように、返信タイプはFoo?からself?に変更されます。あなたはので、このような何かをしようとしたプロトコルでinit Sを宣言することができますまたスウィフトで

protocol JSONInitializable { 
    init?(fromJSON: NSDictionary) throws 
} 

extension Foo: JSONInitializable { 
    required init?(fromJSON: NSDictionary) throws { 
     //Possibly throws or returns nil 
    } 
} 
+0

私は、あなたが必要と思う '便利'とその拡張子で '必須' – smac89

+0

'必要'が必要です。必ずしも「利便性」は必要ない。また、Objective-Cプロトコルは、初期化子がプロトコルの一部であると宣言できていることにも言及する価値があります。詳細は、[NSCodingプロトコル(https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/)を参照してください。 – nhgrif

+0

私はちょうどこの方法で試してみましたが、エラーは、非最終的なクラスの定義でこれを行うことができない、つまり拡張機能が動作しないと言っています – smac89

関連する問題