在父类上创建一个可以被其所有子类访问的函数

时间:2017-01-13 23:08:53

标签: ios swift class

我试图在父类中创建一个可以被其子类访问的函数。我所拥有的问题是函数的一部分,它指的是需要在子类中发生的init。我收到一个错误:

  

传递给不带参数的调用的参数

我不完全确定如何在没有复制的情况下将该功能提供给它的子类,并将其粘贴到每个子类中。

这是父类:

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
  }
}

1 个答案:

答案 0 :(得分: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)

            }

        }

    }

}

该功能必须是通用的,以避免您看到的错误&#39;协议类型无法实例化&#39;。使用符合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")
}