【问题标题】:'self' used before super.init call and property not initialized at super.init call在 super.init 调用之前使用的“self”和在 super.init 调用时未初始化的属性
【发布时间】:2016-06-06 22:12:41
【问题描述】:

我正在尝试在我的自定义 UIView 中初始化一个 Int 数组:

var graphPoints:[Int]

required init?(coder aDecoder: NSCoder) {
    RestApiManager.sharedInstance.requestData() { (json: JSON) in
        for item in json[].array! {
            let n=item["n"].intValue
            print(n)
            if(n>=0) {
                self.graphPoints.append(n)
            }
        }
    }
    super.init(coder: aDecoder)
}

但是在这一行RestApiManager.sharedInstance.requestData() { 我收到了这个错误:'self' used before super.init call

在这一行 super.init(coder: aDecoder) 出现错误:属性 self.graphPoint 未在 super.init 调用时初始化

【问题讨论】:

  • 我认为你需要把super.init(coder: aDecoder)放在你的其他代码之前,我认为第二个问题已经被@user1941284解决了
  • init 中进行异步网络调用是个坏主意
  • @Paulw11 我把异步网络放在哪里?
  • 有很多方法。我可能会创建一个封装服务器 API 的类。它将有一个方法发出请求并通过闭包返回该类的实例。或者由于这是一个 UIView 子类,您可以在 graphPoints 上定义一个设置器来更新视图,并在其他地方检索数据。将视图和服务器 API 紧密耦合是一种糟糕的设计

标签: ios swift uiview


【解决方案1】:

Swift 要求在调用super.init() 之前初始化所有参数。有几种方法可以做到这一点。

使用空初始化器声明 graphPoints,如下所示:

var graphPoints:[Int] = []   or var graphPoints = [Int]()

您还可以将 graphPoints 更改为 Optional,如下所示:

var graphPoints:[Int]?

你也可以不做声明,在调用 super.init() 之前将它初始化为一个空数组

您还需要将 RestAPI 调用移到 super.init 调用下方。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    这里有几个单独的问题

    第一个相关的两个问题是在引用 self 之前必须调用 super.init 方法。只需将此行移到 init 方法的开头即可。

    不幸的是,因为您正在执行异步请求,这仍然会导致您遇到 cmets 中提到的问题。

    另外,请注意init?(coder aDecoder: NSCoder) 不适用于此用途。另一个问题是,如果您从 API 请求数据,您应该创建一个模型对象。与直接创建 UIView 不同,然后当您希望将其显示给用户时,请从该模型创建 UIView

    class GraphPointsModel {
      var graphPoints:[Int]
    
      init(graphPoints: [Int]) {
        self.graphPoints = graphPoints
      }
    
      class func retreiveGraphPoints(handler: (GraphPointsModel -> ())) {
        RestApiManager.sharedInstance.requestData() { (json: JSON) in
          //Error checking...
    
          //Create instance of GraphPointsModel
          let instance = GraphPointsModel(...)  
    
          //Call handler to do with as you wish with result
          handler(instance)
        }
      }
    
    }
    

    【讨论】:

    • 在我当前的项目中,将self.init() 放在异步完成块中会导致神秘的编译错误 - 分段信号 9 和/或 11。显然是通往黑暗面的道路。通过使用DispatchQueue.main.sync { <#code#> } 修复
    【解决方案3】:

    也许你必须这样做:

    super.init(coder: aDecoder)
    

    把它放在你的 requestData 调用之前。

    【讨论】:

    • this call self = super.init(coder: aDecoder) on swift,从编译器跳出错误“无法赋值:‘self’是不可变的”
    猜你喜欢
    • 2020-07-06
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    相关资源
    最近更新 更多