Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialReed Carson
8,306 PointsGuard Statements in Initializer fail to initialize all values
I followed this course after 2.0 came out so instead of using if let I used guard statements just to practice doing so. Im familiar with them, use them all the time and know the proper syntax. However I was pulling my hair out because there was one error at the bottom of my initializer: "return from initializer without initializing all stored properties".
I even set the values to nil in the else part of the guard just in case, but it still wouldn't compile. I quadruple checked multiple times that I had everything set. The only difference in code was my use of guard statements. Is this a known issue?
struct DailyWeather {
let maxTemp: Int?
let minTemp: Int?
let humidity: Int?
let precipChance: Int?
var summary: String?
var icon: UIImage? = UIImage(named: "default.png")
var largeIcon: UIImage? = UIImage(named: "default_large.png")
var sunriseTime: String?
var sunsetTime: String?
var day: String?
let dateFormatter = NSDateFormatter()
init(dailyWeatherDictionary: [String:AnyObject]) {
minTemp = dailyWeatherDictionary["temperatureMin"] as? Int
maxTemp = dailyWeatherDictionary["temperatureMax"] as? Int
guard let humidityFloat = dailyWeatherDictionary["humidity"] as? Double else { humidity = nil ; return }
humidity = Int(humidityFloat * 100)
guard let precipFloat = dailyWeatherDictionary["precipProbability"] as? Double else { precipChance = nil ; return }
precipChance = Int(precipFloat * 100)
summary = dailyWeatherDictionary["summary"] as? String
guard let
iconString = dailyWeatherDictionary["icon"] as? String,
iconEnum = Icon(rawValue: iconString) else { icon = nil ; largeIcon = nil ; return }
(icon, largeIcon) = iconEnum.toImage()
guard let sunriseDate = dailyWeatherDictionary["sunriseTime"] as? Double else { sunriseTime = nil ; return }
sunriseTime = timeStringFromUnixTime(sunriseDate)
guard let sunsetDate = dailyWeatherDictionary["sunsetTime"] as? Double else { sunsetTime = nil ; return }
sunsetTime = timeStringFromUnixTime(sunsetDate)
guard let time = dailyWeatherDictionary["time"] as? Double else { day = nil ; return }
day = dayStringFromUnixTime(time)
}
(methods follow)
1 Answer
Michael Hulet
47,913 PointsAll properties have to be initialized before any guard statement
returns. Thus, you make sure that every property is initialized before the
elsestatement of any
guardstatement finishes. A perhaps faster and easier solution would be to make the initializer itself fail if any of the
guardstatements do. You can do this by making the
initreturn an Optional, and
return nilin the
guard`s where something goes wrong, like this:
init(dailyWeatherDictionary: [String: AnyObject])?{
//Initialize stuff
guard someProperty = dailyWeatherDictionary["someKey"] else{ return nil }
// Initialize more stuff, in case the above guard succeeds
//Repeat as necessary
}