2017-01-13 9 views
0

子クラスにアクセス可能な親クラスで関数を作成しようとしています。私が持っている問題は、その関数の一部が、子クラスで発生する必要のあるinitを指していることです。私はエラーを取得する:親クラスのすべての子クラスにアクセス可能な関数を作成する

Argument passed to call that takes no arguments

私はコピーせずに、それの子クラスの機能が利用できるようにする方法を完全にはわからないと、それぞれの子クラスの中にそれを貼り付けます。ここで

は、親クラスである:

class JSONObject: NSObject { 


    static func updateResultsDictionary(urlExtension: String, completion: 
    @escaping (JSONObject?) -> Void) { 

    let nm = NetworkManager.sharedManager 

    _ = nm.getJSONData(urlExtension: urlExtension) {data in 

     guard let jsonDictionary = nm.parseJSONFromData(data), let 

     resultDictionaries = jsonDictionary["result"] as? 

      [[String : Any]] else { 

      completion(nil) 

      return 
     } 

     for resultsDictionary in resultDictionaries { 

     let jsonInfo = JSONObject(resultsDictionary: resultsDictionary)// Here is where the error "Argument passed to call that takes no arguments" happens 

     completion(jsonInfo) 

     } 
    } 
    } 
} 

これは、サンプルの子クラスである:

class AirBnBObject: JSONObject { 

    var airbnbUS: Int 
    var airbnbLocal: Int 

    init(airbnbUS: Int, airbnbLocal: Int){ 

    self.airbnbUS = airbnbUS 
    self.airbnbLocal = airbnbLocal 
    } 

    init(resultsDictionary:[String: Any]){ 
    guard let cost = resultsDictionary["cost"] as? [String: Any], 
     let airbnb = cost["airbnb_median"] as? [String : Any], 
     let usd = airbnb["USD"] as? Int, 
     let chf = airbnb["CHF"] as? Int 
     else { 
     airbnbUS = 0 
     airbnbLocal = 0 
     return 
    } 

    airbnbUS = usd 
    airbnbLocal = chf 
    } 
} 
+3

エラーが発生しているのは、 'JSONObject'に引数を取るイニシャライザがないためです。 'AirBnBObject'クラスで初期化子を定義しているので、' resultsDictionary'と呼ばれます。 – nathan

答えて

0

私は、プロトコルの代わりにクラスを使用する方に、あなたのJSONObjectを設計することができ、そのように移動しますinit(resultsDictionary:[String:Any])も実装するようクラスを実装するすべてのクラスを要求する必要があります。これにより、プロトコル拡張でupdateResultsDictionary関数を書くことができます(実装するクラスにもその関数を継承させる)。

プロトコルは、次のようになります。

protocol JSONObject: class, NSObjectProtocol { 

    init(resultsDictionary: [String:Any]) 

} 

extension JSONObject { 

    static func updateResultsDictionary<T: JSONObject>(urlExtension: String, completion: 
     @escaping (_ jsonObject: T?) -> Void) { 

     let nm = NetworkManager.sharedManager 

     _ = nm.getJSONData(urlExtension: urlExtension) {data in 

      guard let jsonDictionary = nm.parseJSONFromData(data), 
        let resultDictionaries = jsonDictionary["result"] as? [[String : Any]] else { 

         completion(nil) 

         return 
      } 

      for resultsDictionary in resultDictionaries { 

       let jsonInfo = T(resultsDictionary: resultsDictionary) 

       completion(jsonInfo) 

      } 

     } 

    } 

} 

機能を使用すると、「プロトコルタイプをインスタンス化することはできません」見ていたエラーを回避するために、汎用的にする必要があります。 JSONObject自体ではなくJSONObjectに準拠するTクラスを使用すると、エラーが修正されます。


(ユースTに以下を参照してください、あなたの準拠クラスになることに注意してください)と、任意の実装クラスは、このようなものになります。

class AirBnBObject: NSObject, JSONObject { 

    var airbnbUS: Int 
    var airbnbLocal: Int 

    init(airbnbUS: Int, airbnbLocal: Int){ 

     self.airbnbUS = airbnbUS 
     self.airbnbLocal = airbnbLocal 
    } 

    required init(resultsDictionary:[String: Any]){ 
     guard let cost = resultsDictionary["cost"] as? [String: Any], 
      let airbnb = cost["airbnb_median"] as? [String : Any], 
      let usd = airbnb["USD"] as? Int, 
      let chf = airbnb["CHF"] as? Int 
      else { 
       airbnbUS = 0 
       airbnbLocal = 0 
       return 
     } 

     airbnbUS = usd 
     airbnbLocal = chf 

    } 

} 

このクラスを使用して拡張機能を使用するにはこのようにする必要があります:

AirBnBObject.updateResultsDictionary(urlExtension: "") { (_ jsonObject: AirBnBObject?) -> Void in 
    print("update results dictionary") 
} 
+0

ありがとうございますが、私のプロジェクトで試してみると、プロトコルタイプ 'JSONObject'をインスタンス化できません。jsonInfo = JSONObject(resultsDictionary:resultsDictionary)コード行 – SwiftyJD

+0

ああ、うん!申し訳ありません、私は電話でこれをやっています。明日は別の解決策を書くつもりです。 –

+0

いいですね。ありがとう! – SwiftyJD

関連する問題