Skip to content
Ben Guo edited this page Jul 14, 2015 · 50 revisions

Misc Notes

  • Unwrapping multiple optionals
    • if let email = getEmail(), pw = getPw() {
  • A defer statement defers execution until the current scope is exited. Deferred actions are executed in reverse order of how they are specified.
  • Availability condition
    • if #available(iOS 8.2, OSX 10.10.3, *)
    • * arg indicates that on any other platform, guarded code uses min. deployment target
  • use the @testable attribute in import declarations to allow the unit test target to access any internal entity
  • the optional pattern is useful for iterating across an array of optionals.
    • for case let number? in arrayOfOptionalInts {
  • use class instead of static to define an overrideable type property.
    • class var overrideableComputedTypeProperty: Int {
  • variable type properties can be used to track state across all instances
  • @noescape guarantees a parameter won't outlive the lifetime of a call
  • use @warn_unused_result to provide a warning message about incorrect usage of a nonmutating method that has a mutating counterpart.
  • use @objc to expose to objective c

Error Handling

  • throws, do-catch, try, try!
func vend(itemNamed name: String) throws { ... }

do {
    try vend(itemNamed: "Candy Bar")
} catch VendingMachineError.InvalidSelection {
    print("Invalid Selection.")
} catch VendingMachineError.OutOfStock {
    print("Out of Stock.")
}
  • try! disables error propagation – use only if you're sure that something won't throw.
  • rethrows indicates a function only throws an error if one of its function parameters throws an error
func functionWithCallback(callback: () throws -> Int) rethrows {
    try callback()
}

Labeled Statements

gameLoop: while square != finalSquare {
    switch square + diceRoll {
    case finalSquare:
        break gameLoop
    case let newSquare where newSquare > finalSquare:
        continue gameLoop
    default:
        square += board[square]
    }
}

@autoclosure

  • An autoclosure function captures an implicit closure over the specified expression, instead of the expression itself.
func simpleAssert(@autoclosure condition: Void -> Bool, _ message: String) {
    if !condition() {
        print(message)
    }
}
let testNumber = 5
simpleAssert(testNumber % 2 == 0, "testNumber isn't an even number.")

weak vs unowned

  • weak references are optional. ARC will set a weak reference to nil when the instance it references is deallocated.
  • unowned references are non-optional. Accessing an unowned reference after the instance it references is deallocated will trigger a runtime error.

Capture Lists

Define a capture list to resolve a strong reference cycle between a closure and a class instance.

lazy var someClosure: (Int, String) -> String = {
    [unowned self, weak delegate = self.delegate!] (index: Int, stringToProcess: String) -> String in
    // closure body goes here
}

lazy var someOtherClosure: Void -> String = {
    [unowned self, weak delegate = self.delegate!] in
    // closure body goes here
}

Links