2017-02-22 2 views
3

Хорошо, так что просто начать, мой код Хереса:«я» захвачено закрытием до того были инициализированы все члены

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. Я знаю, что это не самый надежный способ сделать это, но я пытаюсь сначала заставить его работать.

Первая ошибка:

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

на линии DarkSkyClient(apiKey: "").getForecast(latitude: Utils().getLat(), longitude: Utils().getLong()) { result in

Моя вторая ошибка:

Return from initializer without initializing all stored properties

на втором к последнему }

Теперь, очевидно, я m не инициализирует право. Я не могу найти правильный способ сделать то, что моя конечная цель. Может быть, я делаю это совершенно неправильно?

+3

Объект не может асинхронно инициализировать себя. Ваш вызов API должен вызываться другим объектом, который должен вызывать инициализатор для вашего класса «Погода» и передавать значения, полученные из API. – dan

+0

@dan Я понимаю эту часть, я просто не понимаю, как правильно это сделать, с другим объектом. (Также спасибо за помощь) –

+0

Вы можете объявить свои переменные-члены как опции – odlund

ответ

2

Я бы чтобы угадать, что вы столкнулись с проблемой параллелизма. Вероятно, вы пытаетесь получить доступ к свойствам вашего объекта до того, как возвращается асинхронный вызов DarkSkyClient (мои извинения заранее, если я ошибаюсь). т.е. порядок событий ...

  1. объект Погода инициализируется, установив температуру до 0
  2. Позвоните, чтобы начинается DarkSkyClient, работает в фоновом режиме
  3. Чтение переменной температуры - Эй, это 0!
  4. Звонок в DarkSkyClient завершает, устанавливает значение темпа, которое вы действительно хотели. Bad

Так что вам действительно нужно сделать, это перейти к инверсии шаблона управления:

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, это стоит ваше время, чтобы прочитать на предмет; это может быть очень сложно (к сожалению, у меня нет рекомендаций по хорошему праймеру). Надеюсь, это поможет!

+0

Почему с еще дополнительной функцией init() вызывают ту же проблему? – Retro

+0

Пожалуйста, объясните мне, как он может иметь проблему параллелизма, когда код даже не компилируется? – gnasher729

3

Вы должны варианты, объявить свойства, дополнительными опциями, или инициализировать их значения по умолчанию (это означает, что они будут не-OPTIONALS)

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

или

var temp: Float=0 
var condition: String="" 
var wind: Float=0 
var precip: Float=0 
+1

Во втором варианте измените все значения «0» на «0.0», и вы можете удалить все явные объявления типов. – rmaddy

+1

@rmaddy прав, более чистое решение – omarzl

+0

@rmaddy Это сделало бы их 'Double's (что может быть или не желательно) – Hamish

Смежные вопросы