Solution
A mutable object allows for change. An immutable object does not allow for changes.
Mutable object L
var currentYear = 2020
currentYear = 2021 // could not come fast enoughImmutable object
let usIndependenceDay = "July 4th"
usIndependenceDay = "February 22nd" // sorry could not compile, this is π±π¨ Independence daySolution
A property observer listens for changes on a object. One can listen for changes when the object is about to get set and when the object actuallly got set.
var age = 20 {
willSet {
print("it's about to get fun")
}
didSet {
print("with great power comes great responsibility")
}
}
age = 21
/*
it's about to get fun
with great power comes great responsibility
*/Solution
A computed property returns the value of a block of calculated logic.
var count: Int {
return elements.count
}Solution
A function that takes another function as an argument or returns a function is said to be a higher order function. This is the fundamental pillar of functional programming.
Solution
A function that calls itself. The two main parts of a recursive function is the base case and the recursive call.
func jobSearch(_ isHired: Bool) {
// base case
guard !isHired else {
print("Woohoo")
print("Everyone's journey is different")
return
}
// recursive call
print("Job searching...")
jobSearch(Bool.random())
}
jobSearch(false)
/*
Job searching...
Job searching...
Job searching...
Woohoo
Everyone's journey is different
*/ Solution
Access control provide varied level of access to parts of the code of an object from another source object.
Three examples are:
- private
- public
- internal
Solution
Hashable. Types conforming to Hashable will be guaranteed to be unique.
CaseIterable. Enums conforming to CaseIterable will make all their cases available and iterable.
CustomStringConvertible. Conforming to CustomStringConvertible allows a type to override the description property on an object and return a custom String.
Solution
To be able to mutate via referencing the data outside the scope of a function.
Solution
Example 1:
let arr = [1, 2, 3, 4]
print(arr[arr.count - 1]) // assuming the array is not empty, will crash otherwise Example 2:
let arr = [1, 2, 3, 4]
print(arr.last ?? -1) // using nil-coelescing here as last is an optionalSolution
In Swift an optional is a type used to indicate that an object can or not have a value.
Solution
Closures are anonymous functions (functions without a name) that capture references to values in their surrounding context. This is one of the subtle differences between functions and closures. Please note however that nested functions also capture their surrounding values.
// someFunc definition with a closure parameter
func someFunc(action: (Int, Bool) -> ()) {
let internalValue = 20
action(8 + internalValue, Bool.random()) // the action closure captures the Int and Bool values
}
// someFunc call using trailing closure syntax
someFunc { intValue, boolValue in
print("closure captured values are \(intValue) and \(boolValue)") // closure captured values are 28 and false
}Solution
Grand central dispacth is the library that iOS uses to handle concurrency.
Solution
while, for-in and repeat-while
Solution
For user input or STDIN when working in a command-line application we use readLine().
Solution
The keys need to conform to Hashable.
Solution
A paradigm used in programming to represent objects and encapsulate their properties and functions.
// Parent class
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
func info() {
print("Hi, my name is \(name)")
}
}
// Fellow inherits from the Person class
// Subclass
class Fellow: Person {}
let fellow = Fellow(name: "Xavier Li", age: 23)
fellow.info() // Hi, my name is Xavier LiSolution
Inheritance, Encapsulation and Polymorphism.
Solution
In Swift this is a paradigm used to describe the blueprint of functions and properties that a conforming object needs to adhere to.
import UIKit
protocol Vehicle {
var wheels: Int { get }
var color: UIColor { set get }
func drive(speed: Int)
}
struct Bike: Vehicle {
let wheels = 2
var color = UIColor.systemGray
func drive(speed: Int) {
print("current speed is \(speed)")
}
}
let bike = Bike()
bike.drive(speed: 23) // current speed is 23Solution
Dependency Injection is used to pass all required properties and data over to an object. This is better done through the use on an initializer as the object can fully encapsulate its properties.
Solution
XCTest
Solution
A singleton is making use of one instance of a class throughout the life of the launch of an application. One of the main pillars of singleton is the use of marking initializers private so accidental creation of multiple instances is prohibited.
Singletons are used throughout iOS in places like UserDefaults.standard, FileManager.default and UIApplication.shared.
class GameSession {
static let shared = GameSession()
private init() {
// initialization of properties here
}
}
let session = GameSession.shared
let otherSession = GameSession() // 'GameSession' initializer is inaccessible due to 'private' protection levelSolution
URLSession is part of the Foundation framework.
Solution
Compile time errors occurs during the writing phase of your code. Runtime erros occurs during the launch and actual use of the application.
Solution
Index out of range is a runtime error.
Solution
Structs are passed-by value (value-types) meaning copies of the objects are passed around thereby making the objects immutable by default. Classes are reference types and their state is easily mutated as objects that have the same reference can make changes at will.
Solution
Type annotation is explicity marking the data type of a variable or constant upon initialization.
let emojiCharacter: Character = "π"Solution
Type inference is allowing the Swift compiler to determine the data type.
let names = ["Bob", "Anne", "Ashley"] // in this example the names is infereed to be of type [String]Solution
NSString is an objective-c API and is a class. With interopobality we can easily bridge between Swift String and NSString.
Solution
The frame represents an object's superview and it's relationship in the coordinate space, whereas the bounds represents the objects own size and location.
Solution
final class BlackJack {
// properties
// initializer
// methods
}
class MyBlackJack: BlackJack { // COMPILER ERROR: cannot inherit from a final class
}