当前位置: 首页 > 面试题库 >

在初始化所有成员之前,闭包捕获了“自我”

高嘉树
2023-03-14
问题内容

好了,那么,从这里开始,这里是我的代码:

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)

            }

        }

    }

}

因此出现错误,因为我试图在API调用中初始化temp。我知道这不是最可靠的方法,但我正在尝试首先使其起作用。

第一个错误是:

在初始化所有成员之前,闭包捕获了“自我”

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

我的第二个错误:

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

在倒数第二 }

现在,显然我没有初始化正确。但是,我找不到执行最终目标的正确方法。也许我这样做完全错误?


问题答案:

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

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

因此,您真正需要做的是切换到控制模式的反转:

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

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



 类似资料:
  • 问题内容: 在下一堂课 编译器失败并显示以下消息 据我所知,没有运算符读取`self.value。该消息似乎有些混乱。 我不小心想到了一种解决方法。我应该说这让我更加困惑: 在构造函数中声明和初始化它可以使代码编译。 如果有人可以解释为什么在第一种情况下会发生错误,而在第二种情况下编译器会更快乐,那么这将是一个巨大的帮助。 问题答案: 该错误信息的原因是nil-coalescing运算符定义为 并

  • 问题内容: 我最近刚与Python中的一个错误作斗争。那是那些愚蠢的新手错误之一,但是它让我思考了Python的机制(我是C ++的老程序员,是Python的新手)。我将列出错误的代码并解释如何解决该问题,然后我有两个问题。 场景:我有一个叫做A的类,它有一个字典数据成员,下面是其代码(当然这是简化的): 使用此代码的类为B类: 请注意,每次调用都会初始化类A的新“干净”实例,并在添加前后打印字典

  • 问题内容: 也许这比技术问题更像是一种样式问题,但是我有一个包含多个成员变量的类,并且我想让它起作用,以便在用户第一次创建该类的实例时初始化一些成员变量(即在该功能),我想其他的成员变量从成员函数参数,将稍后被称为定义。所以我的问题是我应该初始化函数中的所有成员变量(并将稍后定义的变量设置为虚拟值)还是初始化函数中的某些成员以及后续函数中的某些成员变量。我意识到这可能很难理解,因此这里有一些示例。

  • 此代码编译: 该代码不: 报告的错误(在 MSVC、gcc 和 clang 中)表明他们认为 构造函数未定义或不是 ,例如。从叮叮当当: 为什么? (可能与这个问题有关,但在使用时应该是完整的;只有仍然不完整。

  • 本文向大家介绍Visual Basic .NET成员初始化,包括了Visual Basic .NET成员初始化的使用技巧和注意事项,需要的朋友参考一下 示例 每个枚举成员可以用一个值初始化。如果未为成员指定值,则默认情况下将其初始化为0(如果它是成员列表中的第一个成员),或者初始化为比前一个成员的值大1的值。            

  • 在 Swift 3 中,dispatch_once函数被删除,迁移指南建议使用初始化闭包: 让myGlobal = { … global包含对闭包调用的初始化…}() _ = myGlobal //使用myGlobal只会在首次使用时调用初始化代码。 我想从初始化闭包中访问“Self”实例变量,如下所示: 为什么“自我”在闭包中是不可接近的,如何才能使它成为现实?