App Development with Swift study materials
App Development with Swift study resources

App Development with Swift flashcards

App Development with Swift · Build recall with a focused review session.

32 cards. Read the term and the definition here. The deck at the top of this page is optional.

let versus var
let declares a constant that may be assigned only once; var declares a mutable variable. Both infer their type at compile time from the initializer.
Type inference
The compiler derives a declaration's type from its initializer, so writing let count = 0 gives count the type Int without any explicit annotation.
Value type copying
Structures, enumerations, and tuples are value types: assigning or passing one copies it, so mutating the copy never changes the original value.
Explicit numeric conversion
Swift never converts between numeric types implicitly. Writing Int(3.9) truncates toward zero, and a Double must be converted explicitly before use in Int arithmetic.
Identity operator
The === operator reports whether two class references point to the same instance, while == reports value equality and requires the type to conform to Equatable.
Access control levels
From narrowest to widest: private limits use to the enclosing declaration and same-file extensions, fileprivate to the file, internal to the module as the default, then public and open.
Switch exhaustiveness and fallthrough
A switch must cover every possible value of the matched type, and each case ends automatically; only the fallthrough keyword continues execution into the following case body.
guard else must exit
A guard statement requires its else block to leave the current scope by returning, breaking, continuing, throwing, or calling a Never-returning function; successful bindings stay in scope afterwards.
Default argument labels
A function parameter's name is also its external label at the call site; prefixing the name with an underscore removes that label, and a default value makes the argument omittable.
inout parameters
An inout parameter lets a function modify the caller's variable in place; the call site must pass a mutable variable prefixed with an ampersand, not a literal or constant.
Escaping closures
Closures are non-escaping by default, meaning they cannot outlive the call. Marking a parameter @escaping allows the closure to be stored or invoked later, as completion handlers are.
Closure capture lists
A capture list written before a closure's parameters, such as [weak self], defines how the closure holds captured references and is the standard remedy for retain cycles.
Memberwise initializer
A structure without a custom initializer receives a synthesized memberwise initializer that takes every stored property in declaration order; classes receive no such initializer.
Struct versus class
Structures are value types with memberwise initializers and no inheritance; classes are reference types that support inheritance, deinitializers, and identity comparison with the triple-equals operator.
mutating methods
Methods on a structure or enumeration that assign to stored properties must be marked mutating, because instances are value types and self is treated as a constant inside methods.
Class initializer phases
A designated initializer must set every stored property before using self or calling a method; convenience initializers delegate with self.init, and deinit runs when the instance is deallocated.
Enum associated values
An enumeration case may store associated values of any type in parentheses after its name; a switch with case let .name(value) extracts them for use in the case body.
Raw value enumerations
Giving an enumeration a raw type such as String or Int assigns each case a rawValue, implicit or explicit, and adds a failable init?(rawValue:) for converting back from the raw value.
Protocol extension defaults
A protocol extension can provide a default implementation for a requirement, inherited by conforming types that do not implement their own version; members declared only in extensions dispatch statically.
Synthesized Codable
A type conforms to Codable automatically when all of its stored properties are Codable; the compiler generates encoding and decoding keyed by property names unless CodingKeys are defined.
compactMap versus map
compactMap applies a transform that may return nil and discards those results, producing a non-optional array; map keeps every result, so an optional-returning transform yields an array of optionals.
Optional chaining
Placing a question mark after an optional value, as in person?.address?.city, short-circuits to nil when any link is nil and otherwise wraps the final result in an optional.
Nil-coalescing operator
The double-question-mark operator evaluates to the wrapped value of the optional on its left when that value is not nil, and to the default value on its right otherwise.
try? versus try!
try? turns a thrown error into a nil optional result; try! traps at runtime if an error is thrown, so it is reserved for failures that cannot possibly occur.
Dictionary subscript behavior
Reading a dictionary through a key subscript returns an optional that is nil when the key is missing; assigning nil to that subscript removes the existing key-value pair.
Custom Error conformance
Any type conforming to the Error protocol can be thrown from a throws function; enumerations are the usual choice, with one case per failure and do-catch matching cases by pattern.
SwiftUI View body
In SwiftUI a view is a value type conforming to View that returns its content from the computed body property; changing observed state re-evaluates body and updates the rendered hierarchy.
@State versus @Binding
@State declares storage owned by the view that survives body re-evaluation; @Binding references state owned by an ancestor, letting a child read and write it while both stay in sync.
@StateObject versus @ObservedObject
@StateObject creates and retains an ObservableObject for the lifetime of its view; @ObservedObject merely observes an instance that is created and owned somewhere else.
UIViewController lifecycle order
viewDidLoad runs once when the view loads; then viewWillAppear and viewDidAppear precede and follow each on-screen appearance, mirrored by viewWillDisappear and viewDidDisappear when leaving.
Main-thread UI updates
UIKit and SwiftUI require interface updates on the main thread, so results computed in the background must be handed back with MainActor.run or DispatchQueue.main.async.
NavigationStack in SwiftUI
NavigationStack manages a stack of pushed screens and works with NavigationLink or navigationDestination to present detail views, replacing the deprecated NavigationView container.