在所有成员初始化之前,由关闭捕获的"自我"

Cha*_*uck 9 swift

好吧,只是为了开始,继承我的代码:

import UIKit
import ForecastIO

class Weather {
    var temp: Float
    var condition: String
    var wind: Float
    var precip: Float

    init() {
        DarkSkyClient(apiKey: "<api key>").getForecast(latitude: Utils().getLat(), longitude: Utils().getLong()) { result in

            switch result {
            case .success(let currentForecast, _):

                self.temp = (currentForecast.currently?.temperature)!
                self.condition = (currentForecast.currently?.summary)!
                self.wind = (currentForecast.currently?.windSpeed)!
                self.precip = (currentForecast.currently?.precipitationProbability)!

            case .failure(let error):
                print(error)

            }

        }

    }

}
Run Code Online (Sandbox Code Playgroud)

所以我的错误出现了,因为我正在尝试初始化API调用内部的temp.我知道这不是最可靠的方法,但我试图让它开始工作.

第一个错误是:

在所有成员初始化之前,由关闭捕获的"自我"

在线上 DarkSkyClient(apiKey: "").getForecast(latitude: Utils().getLat(), longitude: Utils().getLong()) { result in

我的第二个错误:

从初始化程序返回而不初始化所有存储的属性

在倒数第二个 }

现在,显然我没有正确初始化.我无法找到正确的方法来完成我的最终目标.也许我这样做完全错了?

小智 7

您有两个选项,将属性声明为选项,或使用默认值初始化它们(这意味着它们将是非选项)

var temp: Float?
var condition: String?
var wind: Float?
var precip: Float?
Run Code Online (Sandbox Code Playgroud)

要么

var temp: Float=0
var condition: String=""
var wind: Float=0
var precip: Float=0
Run Code Online (Sandbox Code Playgroud)


小智 6

我敢猜测您遇到了并发问题。您可能正在尝试在对 DarkSkyClient 的异步调用返回之前访问对象的属性(如果我弄错了,请提前道歉)。即,事件的顺序是......

  1. 天气对象已初始化,将 temp 设置为 0
  2. 开始调用 DarkSkyClient,在后台运行
  3. 读取临时变量 - 嘿,它是 0!
  4. 对 DarkSkyClient 的调用完成,将 temp 设置为您真正想要的值。坏的

所以你真正需要做的是切换到控制模式反转:

class Weather {
    var temp: Float
    var condition: String
    var wind: Float
    var precip: Float

    init(forecast: Forecast) {
        temp = (forecast.currently?.temperature)!
        condition = (forecast.currently?.summary)!
        wind = (forecast.currently?.windSpeed)!
        precip = (forecast.currently?.precipitationProbability)!
    }

    static func getWeather() {
        DarkSkyClient(apiKey: "<api key>").getForecast(latitude: Utils().getLat(), longitude: Utils().getLong()) { result in

            switch result {
            case .success(let currentForecast, _):
                let weather = Weather(forecast: currentForecast)
                // Display the weather somewhere
                doSomethingWith(weather: weather)
            case .failure(let error):
                print(error)
            }
        }
    }    
}
Run Code Online (Sandbox Code Playgroud)

如果您不熟悉使用异步 API 进行开发,那么值得花时间阅读该主题;这可能非常棘手(遗憾的是,我没有任何关于好的入门书的建议)。希望这可以帮助!

  • 请向我解释当代码甚至无法编译时他怎么会遇到并发问题? (2认同)

Win*_*ter 5

对我来说,这是因为我没有调用super.init()初始化程序。

class AnObject: NSObject {
    override init() {
//        super.init()

        let _: ()-> (Void) = {
            print(String(describing: self))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案之所以有效,是因为你、我以及你的答案的其他 16 个投票者可能对情况略有不同:我们的问题类继承自 NSObject。 (4认同)