Bob Lee Course Part 12 (consolidation of lectures 17-20)
Before I begin the much-needed consolidation blog, I feel the need to introduce something into my weekly repertoire. Each week, I am going to work on a specific Xcode project! the reason why is that Bob's course is totally separate to the main Xcode project stuff - it's all on playgrounds. That's fine as I am really learning the syntax but I am also losing touch with the practical element of getting code for a potential app together.
Computed Properties
MY TAKE - These are different to 'stored' properties in that some sort of calculation or computation is required to get or set the value. I could have for example within a shape the computed property of area, which would take in the stored property of length (if square - that's all needed actually), then the area can be calculated. This is INSTEAD OF USING A FUNCTION! That was the key bit, yes! You can also have get (where you put in the calculation needed etc.). The set bit means what you can set the property to, which would also change the stored properties that were used in calculating this - so the 'newValue' would be changed to. Sounds a bit confusing!
Pretty much right! The issue here was that not all of the code worked before on Xcode. And still doesn't!
This should do but doesn't want to:
MY TAKE - This is building in an optional within the init (a ? after the init keyword) so that if there is no value, then error handling code is built in. Basically. To be honest, I don't see the advantage of using it over specific error handling code with enums and with the specific error messages.
So this week I will focus on making a specific project. To start with, it will be a rework of something I have done before with Angela. I'm choosing her because her practical courses have been the most accessible and frankly the best. So after this consolidation entry, I will do an additional one to review what I have done since picking Swift back up in June - some 5 months ago.
Also, for this entry, I'm adding in a 'MY TAKE' - so I can make it clearer what I know before revising any content. This is a good way of testing and challenging myself to show what I know!
Start Time - 11:33
Convenience Init
MY TAKE - so this is using the specific keyword 'convenience' so that an object can just be created with () - no initial values required. So basically if I did let course = MyCourse(), then straight away, a value would be attributed to any store properties. It all essentially means that an object can be created without having to put in those values in the init process.
Yes! Spot on! Here is the example I used before (Bob Lee Course Part 10 blog):
class Human {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "Jeff Green")
This means that I can create a new object e.g. var newPerson = Human(). The empty brackets will mean that "Jeff Green" is give as the stored property for name. Simple!
Real life application - colours. When I tried this before there were various errors on Xcode. Let's try again since it has been updated!
Awesome. This now works:
let randomColour = UIColor(red: 255/80, green: 80/255, blue: 85/255, alpha: 1)
extension UIColor {
convenience init(r: CGFloat, g: CGFloat, b: CGFloat) {
self.init(red: r/255, green: g/255, blue: b/255, alpha: 1)
}
}
let newColour = UIColor(r: 45, g: 33, b: 199)
I changed the type to CGFloat - that seemed to make it happy!
So now I can use UIColor to put in the key values for r, g and b. Then the rest is done! So it is not empty brackets, but LESS information in the brackets that makes it 'convenient'. Got it!
MY TAKE - These are different to 'stored' properties in that some sort of calculation or computation is required to get or set the value. I could have for example within a shape the computed property of area, which would take in the stored property of length (if square - that's all needed actually), then the area can be calculated. This is INSTEAD OF USING A FUNCTION! That was the key bit, yes! You can also have get (where you put in the calculation needed etc.). The set bit means what you can set the property to, which would also change the stored properties that were used in calculating this - so the 'newValue' would be changed to. Sounds a bit confusing!
Pretty much right! The issue here was that not all of the code worked before on Xcode. And still doesn't!
This should do but doesn't want to:
var diameter: Double {
get {
return radius * 2
}
set {
radius = newValue / 2
}
}
Ok the below does work. Within the struct all is peachy but not when doing the separate variables. How strange!
struct Square {
var side: Double
var area: Double {
get {
return side * side
}
set {
side = sqrt(newValue)
}
}
}
let square1 = Square(side: 5)
square1.area
square1.side
Anyway, in the above, square1.area returns 25 - it uses the 'get' code; when I then access the side, it uses the 'set'.
Hang on...hang on, that's not quite right. The whole point of 'get' is that the area can be calculated, using the value of the side (that's put in via init, got that). But for set, that actually means I can SET the computed property of area to be e.g. 36.
square1.area = 36
square1.side
So square1.side would reveal 6, rather than 5. This is because of the set block of code, as the AREA HAS BEEN SET AS ANOTHER VALUE! NOW I GET IT!!
Property Observers
*This was only looked at yesterday as was the next one!
MY TAKE - These are used for tracking data. You have willSet and didSet. willSet will print output to the console when the value is being changed, then the didSet will do so when it has actually changed. Real life examples could be when changing login details like usernames or background colours, pop ups etc.
Example (from Bob Lee Course Part 11 blog):
var myGrade: Int = 80 {
willSet {
print("Hey something happened!")
}
didSet {
print("Hey something else happened!")
}
}
Like with computed properties (get/set), you have newValue and oldValue as the default temporary constants that can be accessed. You can of course put in your own specific value names for these if you want to. These would go directly after willSet/didSet in brackets.
You can also use if statements within these:
var loggedIn: Bool = false {
willSet {
print("The user has tried something")
}
didSet {
if loggedIn {
print("The user has switched from \(oldValue) to \(loggedIn)")
}
}
}
Cool, all of that is good and makes perfect sense!
Failable Init
class Blog {
let name: String
init?(name: String) {
if name.isEmpty {
return nil
}
self.name = name
}
}
So with this class example, the if name.isEmpty, means that nil can be returned. That means it' safer code.
So this is why I don't quite get it. I've just done another class without the init? - just the normal one.
class BlogTwo {
let name: String
init(name: String) {
self.name = name
}
}
let myLatestBlog = BlogTwo(name: "")
print(myLatestBlog.name)
The program did not crash. But there was not an error message returned. So I guess the advantage of the failable init is that 'nil' can be returned. Still don't quite get this so let's find out more!
Reading on the Swift website, it basically states that you use the failable init when you may have invalid parameter values, not enough external information etc. Whatever it is, then the failable part means that nil can safely be returned, or an error message.
This was the example from before for using optional binding:
let newBlog = Blog(name: "BBB")
if let blog = newBlog {
print(blog.name)
} else {
print("No value")
}
So that is implicit unwrapping used. OK, fair enough for now.
Finish Time - 12:25 (Total Time 52 minutes)
Well, as always with consolidation entries, that was so useful. Always worth it. In a bit, I'm going to do an 'update' blog, which will be a trail through of what I have learned since picking Swift up again in June. It will hopefully be a good summary of what I've done, where I'm at and what I need to do.
Comments
Post a Comment