'self' captured by a closure before all members were initialized

前端 未结 3 2087
囚心锁ツ
囚心锁ツ 2020-12-11 01:02

Alright, so just to start off, heres my code:

import UIKit
import ForecastIO

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


        
相关标签:
3条回答
  • 2020-12-11 01:34

    For me, it's because I didn't call super.init() in the initializer.

    class AnObject: NSObject {
        override init() {
    //        super.init()
    
            let _: ()-> (Void) = {
                print(String(describing: self))
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-11 01:38

    I'd hazard to guess that your are running into a concurrency problem. You are probably trying to access your object's properties before the asynchronous call to the DarkSkyClient returns (my apologies in advance if I got this wrong). i.e., the order of events is...

    1. Weather object is initialized, setting temp to 0
    2. Call to DarkSkyClient begins, runs in the background
    3. Read temp variable - hey, it's 0!
    4. Call to DarkSkyClient completes, sets the temp to the value you really wanted. Bad

    So what you really need to do is switch to an inversion of control pattern:

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

    If you're not familiar with developing with asynchronous APIs it's worth your while to read up on the subject; it can be very tricky (sadly, I don't have any recommendations for a good primer). Hope this helps!

    0 讨论(0)
  • 2020-12-11 01:42

    You have two options, declare the properties as optionals, or initialize them with a default value (this means they will be non-optionals)

    var temp: Float?
    var condition: String?
    var wind: Float?
    var precip: Float?
    

    or

    var temp: Float=0
    var condition: String=""
    var wind: Float=0
    var precip: Float=0
    
    0 讨论(0)
提交回复
热议问题