Notice: Trying to access array offset on value of type null in /var/www/html/wp-content/themes/anima/includes/loop.php on line 296

Enum

enum FastFoodMenu {
     case hamburger
     case fries
     case drink
     case cookie
   }

enum is value types (like struct)

associated data

enum FastFoodMenu {
  case hamburger(numberOfPatties: Int)
  case fries(size: FryOrderSize)
  case drink(String, ounces: Int) 
  case cookie
}
enum FryOrderSize {
  case large
  case small
}

setting enum value

let menuItem: FastFoodMenu = FastFoodMenu.hamburger(patties: 2)
let otherItem: FastFoodMenu = FastFoodMenu.cookie
or
let otherItem: FastFoodMenu = .cookie

use switch

var menuItem:  FastFoodMenu = FastFoodMenu.hamburger(patties: 2)
switch menuItem {
  case FastFoodMenu.hamburger: print("burger")
  case FastFoodMenu.fries: print("fries")
  case FastFoodMenu.drink: print("drink")
  case FastFoodMenu.cookie: print("cookie")
}

or simply
var menuItem:  FastFoodMenu = FastFoodMenu.hamburger(patties: 2)   
switch menuItem {
  case .hamburger: print("burger")
  case .fries: print("fries")
  case .drink: print("drink")
  case .cookie: print("cookie")
}

use break to skip

var menuItem:  FastFoodMenu = FastFoodMenu.hamburger(patties: 2)   
switch menuItem {
  case .hamburger: break
  case .fries: print("fries")
  case .drink: print("drink")
  case .cookie: print("cookie")
}

use default

var menuItem:  FastFoodMenu = FastFoodMenu.hamburger(patties: 2)   
switch menuItem {
  case .hamburger: print("burger")
  case .fries: print("fries")
  default: print("other")
}

get associated data

var menuItem:  FastFoodMenu = FastFoodMenu.drink("Coke", ounces: 32)
switch menuItem {
  case .hamburger(let pattyCound): print("a burger with \(patthCound) patties")
  case .fries(let size): print("a \(size) order of fries") 
  case .drink(let brand, let ounces): print("a \(ounces)oz of \(brand)") 
  case .cookie: print("cookie")
}

enum can have method but no storage and computed variable

enum FastFoodMenu {
  case hamburger(numberOfPatties: Int)
  case fries(size: FryOrderSize)
  case drink(String, ounces: Int) 
  case cookie
  func isIncludedInSpecialOrder(number: Int) -> Bool {
    switch self {
      case .hamburger(let pattyCound): return pattyCount == number
      case .fries, .cookie: return true
      case .drink(_, let ounces): return ounces == 16
    }
  }
  var calories: Int {}
}

modify self in enum, mutating is must since enum is value types (copy on write)

enum FastFoodMenu {
  ...
  mutating func switchToBeingACookie() {
    self = .cookie
  }
}

Optional just a enum

enum Optional<T> {
  case none
  case some(<T>)
}

Special Optional syntax in swift

The ‘not set’ case has special keyword: nil

The character ? is used to declare an Optional

the character ! is used to ‘unwrap’ the associated data if Optional is in the ‘set’

the keyword if can also used to conditionally get associated data (if let index = xxx …)

An optional declared with ! (instead of ?) will implicitly unwrap (add !) when access (eg. flipCoundIndex: UILabel!)

you can use ?? to create an expression which “default” to a value if an optional is not set (eg. return emoji[card.identifier] ?? “?”)

you can also use ? when accessing an optional to bail out of an expression midstream, this is called optional chaining

example of optional

#+begin_src

var hello: String? var hello: Optional<String> = .none

var hello: String? = “hello” var hello: Optional<String> = some(“hello”)

var hello: String? = nil var hello: Optional<String> = .none

var hello: String? = “Hi” switch hello {

print hello! case .none: // raise exception (crash!) case .some(let data): print(data) }

if let greeting = hello { switch hello {

print (greeting) case .some(let data): print(data) } else … case .none: // do … }

let x: String? = … switch x {

let y = x ?? “foo” case .none: y = “foo” case .some(let data): y = data }

let x: String? = … switch x {

let y = x?.foo()?.bar?.z case .none: y = nil case .some(let data1): switch data1.foo() { case .none: y = nil case .some(let data2): switch data2.bar { case .none: y = nil case .some(let data3): y = data3.z } } } #+end_src

Four essential Data Structure-building concepts in Swift

class

struct

enum

protocol

Class

support object oriented design

single inheritance of both functionality and data

reference types

Heap is kept clean by Swift (via reference counting, not garbage collection)

Memory Management

Automatic Reference Counting

reference types (classes) are stored in Heap

How does the system know when to reclaim the memory for these from heap?

It “counts references” to each of them and when there are zero reference, they get tossed

This is done automatically

It is known as “automatic reference counting” and it is NOT garbage collection

Inference by ARC

Your can inference ARC by how you declare a reference type var with these keywords

strong

weak

unowned

strong: “normal” reference counting, as long as anyone, anywhere has a strong pointer to an instance, it will stay in the heap

weak: weaks means “if no one else is interested in this, then neither am I, set me to nil in this case”

because it has to be nil-able, weak only applies to Optional pointers to reference types

a weak pointer will NEVER keep an object in the heap

Greate Example: outlets (strongly held by the view hierarchy, so outlets can be weak)

unowned:

unowned means “don’t reference count this; crash if I’m wrong”

this is very rarely used

Usually only to break memory cycles between objects

Struct

value types (struct don’t live in heap and are passed around by copying them)

very efficient “copy on write” is automatic in swift

This copy on write behavior required you to mark mutating methods

No inheritance (of data)

Mutability controlled via let (eg, you can’t add elements to an array assigned by let)

Support functional programming design

examples: Card, Array, Dictionary, String, Character, Int, Double, UInt32

Enum

used for variables that have one of discrete set of values

each option for that discrete value can have “associated data”with it

the associated data in the only storage that an enum can have (no instance variables)

value types

can have methods and computed variable

Protocol

a type which is a declaration of functionality only

no data storage of any kind (so it doesn’t make sense to say it is “value” or “reference” types)

essentially provide multiple inheritance

we’ll “ease into” learning about protocols since it is new to most of you