Send a link to your students to track their progress
116 Terms
1
New cards
let vs. var
let binds a value that can never be reassigned; var allows reassignment — defaulting to let is idiomatic Swift and signals intent about what can change
2
New cards
Optional
a type that either holds a value or holds nothing (nil), making "this might be empty" part of the type system so the compiler forces you to handle it
3
New cards
Why optionals exist
they turn a whole class of runtime null-pointer crashes into compile-time errors you're required to address before shipping
4
New cards
Unwrapping
extracting the value inside an optional, safely with if let, guard let, or ??, or unsafely with ! which crashes when the value is nil
5
New cards
if let vs. guard let
both unwrap safely, but if let scopes the value to its own braces while guard let unwraps into the remainder of the function and forces an early exit on failure
6
New cards
Force unwrap (!)
asserting an optional definitely has a value; a crash if you're wrong, which is why it's treated as a red flag outside of cases where nil is genuinely impossible
7
New cards
Optional chaining
calling into a chain that might contain nil using ?., where the entire expression evaluates to nil if any link is nil rather than crashing
8
New cards
Struct vs. class
structs are value types that copy on assignment and can't inherit; classes are reference types that share one instance and support inheritance, deinit, and identity comparison
9
New cards
Value semantics
each owner holds an independent copy, so mutating one never surprises another — this is what makes structs easy to reason about and safe across threads
10
New cards
Reference semantics
every owner points at the same underlying instance, so a mutation through one reference is visible through all of them
11
New cards
When to choose a class
when you need inheritance, a stable identity, Objective-C interop, or genuinely shared mutable state — otherwise reach for a struct
12
New cards
Copy-on-write
Swift's optimization where value types like Array and String share underlying storage until one copy is mutated, giving value semantics without copying on every assignment
13
New cards
Stored property
a property that actually holds a value in the instance's memory
14
New cards
Computed property
a property with no storage of its own that runs a getter (and optionally a setter) to derive its value on every access
15
New cards
willSet / didSet
property observers that fire immediately before and after a stored property changes, letting you react to a change in one place
16
New cards
lazy
defers computing a property's initial value until its first access, useful when the setup is expensive and may never be needed
17
New cards
static vs. instance member
a static member belongs to the type itself and is shared; an instance member belongs to each individual instance
18
New cards
mutating
required on struct and enum methods that modify self, because value type methods can't change their own properties by default
19
New cards
Enum
a type defining a fixed set of related cases, letting the compiler verify you've handled every possibility in a switch
20
New cards
Associated value
extra data attached to a specific enum case, which is how Optional and Result are both built under the hood
21
New cards
Protocol
a contract listing the properties and methods a conforming type must provide, without supplying the implementation
22
New cards
Protocol extension
a default implementation attached to a protocol so conforming types inherit behavior without a class hierarchy
23
New cards
Protocol-oriented programming
composing behavior from small protocols and extensions rather than deep inheritance chains, Swift's preferred design direction
24
New cards
Delegate pattern
one object forwards decisions or events to another it holds a weak reference to, defined through a protocol — the backbone of UIKit's API design
25
New cards
Closure
a block of code that can be stored, passed as an argument, and called later, and that captures variables from where it was defined
26
New cards
Capture semantics
a closure keeps its captured variables alive, which is why a closure capturing self strongly can create a retain cycle
27
New cards
@escaping
marks a closure that outlives the call it was passed into, meaning Swift must keep it and its captures alive beyond the normal scope
28
New cards
[weak self]
a capture list preventing a closure from strongly retaining self, the standard fix for closure-based retain cycles
29
New cards
Generic
code parameterized over a placeholder type so it works across many types while the compiler still enforces type safety at each call site
30
New cards
Type constraint
narrowing a generic placeholder to types conforming to a protocol, e.g. <T: Comparable>, so you can actually use the operations you need
31
New cards
Why generics beat Any
generics keep full compile-time type information and require no casting; Any discards that information and pushes failures to runtime
32
New cards
some vs. any
some is an opaque type — one specific hidden concrete type, resolved at compile time and fast; any is an existential holding varying types at runtime with a performance cost
33
New cards
ARC
Automatic Reference Counting — the compiler inserts retain and release calls so a class instance is deallocated the moment nothing references it
34
New cards
Strong / weak / unowned
strong keeps an object alive; weak doesn't and becomes nil when the object dies; unowned doesn't and crashes if accessed after the object dies
35
New cards
Retain cycle
two objects strongly referencing each other so neither's count ever reaches zero, leaking memory until one side is made weak or unowned
36
New cards
Error handling in Swift
a throwing function declares throws, callers use try inside do-catch, and errors are typically modeled as an enum conforming to Error
37
New cards
try? vs. try!
try? converts a throwing call into an optional that's nil on failure; try! crashes on failure and carries the same risk as force unwrapping
38
New cards
defer
schedules cleanup that is guaranteed to run when the current scope exits, no matter which path it exits through
39
New cards
Result type
a generic enum with success and failure cases used to carry an outcome through a completion handler, where throws can't reach
40
New cards
async / await
lets asynchronous code be written and read sequentially, with await marking the points where the function may suspend without blocking its thread
41
New cards
Suspension is not blocking
awaiting releases the thread so other work can run, unlike a blocking call that holds the thread idle — the most commonly probed concurrency distinction
42
New cards
Task
a unit of asynchronous work, created to call async code from a synchronous context and cancellable as a unit
43
New cards
Actor
a reference type that serializes access to its own mutable state so only one task touches it at a time, eliminating data races without manual locks
44
New cards
@MainActor
marks work that must run on the main thread, which is required for every UI update in UIKit and SwiftUI
45
New cards
Sendable
a compile-time marker that a type is safe to hand across concurrency boundaries because it can't be mutated from two places at once
46
New cards
Access control
private, fileprivate, internal (the default), public, and open — each widening the scope from a single declaration out to other modules
47
New cards
Extension
adds methods, computed properties, initializers, or protocol conformance to an existing type, including types you don't own
48
New cards
map / filter / reduce
map transforms each element, filter keeps elements matching a predicate, reduce collapses a collection into a single value
49
New cards
compactMap vs. flatMap
compactMap transforms and drops nil results; flatMap transforms and flattens nested collections into one level
50
New cards
Equatable / Comparable / Hashable
Equatable enables ==, Comparable enables ordering with <, and Hashable enables use as a Set element or Dictionary key
51
New cards
Codable
a type that can be encoded to and decoded from an external format like JSON, combining Encodable and Decodable
52
New cards
Declarative UI
you describe what the UI should look like for a given state and the framework figures out how to update the screen, rather than issuing step-by-step update instructions as in UIKit
53
New cards
Views are structs
SwiftUI views are cheap value types constantly discarded and recreated — they describe the UI rather than being it, which is exactly why state can't live in a plain property and needs a property wrapper to survive redraws
54
New cards
Source of truth
the single authoritative location a piece of state lives; every other view should bind to or derive from it rather than keeping its own copy that can drift out of sync
55
New cards
@State
local, simple, mutable state owned by one view; mutating it tells SwiftUI to re-render that view — right for a toggle, a text field, or whether a sheet is presented
56
New cards
@Binding
a two-way connection to state owned by another view, letting a child read and write the parent's @State without owning it, passed using the $ prefix
57
New cards
@StateObject
creates and owns a reference-type model for the lifetime of the view that declares it, surviving the view being recreated on every redraw
58
New cards
@State vs. @StateObject
@State is for simple value-type state; @StateObject is for a reference-type model object the view creates and owns
59
New cards
@Observable
a macro applied to a model class that makes its properties automatically trackable, so SwiftUI re-renders only the views that actually read a property that changed
60
New cards
Why @Observable replaced ObservableObject
the old ObservableObject plus @Published pattern notified on any change and re-rendered more than necessary; @Observable tracks per-property, so updates are more granular and efficient
61
New cards
@Environment
injects shared values or models into a deep view hierarchy without threading them through every intermediate initializer, at the cost of making dependencies less explicit
62
New cards
@Bindable
creates bindings into the properties of an @Observable model so child views can write back to it, the @Observable-era counterpart to @Binding
63
New cards
Identifiable in ForEach
gives each list item a stable identity so SwiftUI can tell what was inserted, removed, or moved, which is what makes diffing and animations correct
64
New cards
.task { }
runs async work tied to a view's lifetime and cancels it automatically when the view disappears, unlike the synchronous .onAppear which manages nothing for you
65
New cards
View not updating
debug by checking the right property wrapper is used, that the view actually reads the property that changed, that you aren't holding a stale copy of a value type, and that the mutation happened on the main thread
66
New cards
Data structure
a way of organizing data so specific operations are fast — most design questions are really asking which one you'd pick and why
67
New cards
Array
contiguous ordered storage giving O(1) index access but O(n) insertion or deletion in the middle because elements must shift
68
New cards
Linked list
nodes chained by pointers, giving O(1) insertion and removal at a known position but requiring a walk to find anything
69
New cards
Set
an unordered collection of unique elements with average O(1) membership checks — the right choice when you only care whether something exists
70
New cards
Hash map / dictionary
key-value storage with average O(1) lookup, achieved by hashing the key directly to a storage slot, at the cost of no ordering
71
New cards
Hash collision
two distinct keys hashing to the same slot, handled by chaining entries at that slot or probing for the next open one
72
New cards
Stack
last-in-first-out storage, used for undo history, expression evaluation, call frames, and iterative depth-first traversal
73
New cards
Queue
first-in-first-out storage, used for scheduling, buffering, and breadth-first traversal
74
New cards
Heap / priority queue
keeps the minimum or maximum element instantly retrievable with O(log n) insertion, the standard tool for top-K and scheduling problems
75
New cards
Binary search tree
a tree keeping smaller values left and larger values right, giving O(log n) search when balanced and degrading to O(n) when it isn't
76
New cards
Graph
nodes joined by edges, directed or undirected and weighted or not, used to model networks, dependencies, and relationships
77
New cards
Big O
how runtime or memory scales with input size, with constants and lower-order terms dropped so you're comparing growth rather than raw speed
78
New cards
O(1) / O(log n) / O(n) / O(n log n) / O(n²)
constant, halving, linear, typical efficient sort, and nested-loop growth — knowing which structure gives which is the core of most optimization answers
79
New cards
Amortized cost
the average cost per operation across many operations, which is why appending to a dynamic array counts as O(1) despite occasional resizes
80
New cards
Time-space tradeoff
spending memory to buy speed, most commonly by adding a hash set or map alongside another structure to turn O(n) scans into O(1) lookups
81
New cards
Binary search
halving a sorted range each step to find a value in O(log n), which requires the data to be sorted first
82
New cards
Two pointers
moving two indices through a structure to replace nested loops with a single linear pass
83
New cards
Sliding window
maintaining an expanding and contracting range over a sequence to solve substring and subarray problems in linear time
84
New cards
Recursion
a function solving a problem by calling itself on a smaller input, requiring a base case and consuming stack space per call
85
New cards
Memoization
caching results by input so repeated calls return immediately, converting exponential recursive work into polynomial
86
New cards
Dynamic programming
decomposing a problem into overlapping subproblems and reusing their results rather than recomputing them
87
New cards
BFS vs. DFS
BFS explores level by level with a queue and finds shortest paths in unweighted graphs; DFS goes deep down one branch first using recursion or a stack
88
New cards
LRU cache
a fixed-capacity cache evicting the least recently used entry, classically a hash map for O(1) lookup paired with a doubly linked list for O(1) reordering
89
New cards
Cache
a fast layer storing recently or frequently used results so they don't have to be recomputed or refetched
90
New cards
Cache invalidation
deciding when cached data has gone stale and must be refreshed, notoriously one of the hardest problems in practice
91
New cards
Stack vs. heap memory
the stack holds call frames and locals with automatic cleanup and limited size; the heap holds dynamically allocated objects that persist until freed
92
New cards
Memory leak
allocated memory that is never released and no longer usable, steadily degrading performance until the app is killed
93
New cards
Process vs. thread
a process has its own isolated memory; threads live inside a process and share its memory, which is precisely why they need synchronization
94
New cards
Concurrency vs. parallelism
concurrency is structuring work so multiple things can be in progress at once; parallelism is literally executing them at the same instant on multiple cores
95
New cards
Race condition
a bug where correctness depends on the unpredictable timing of concurrent operations, making it intermittent and hard to reproduce
96
New cards
Read-modify-write hazard
reading a value, changing it, and writing it back — two clients doing this concurrently silently lose one update unless the operation is atomic
97
New cards
Mutex / lock
a primitive letting only one thread enter a critical section at a time, protecting shared mutable state
98
New cards
Thread safety
code that behaves correctly when called from multiple threads, achieved either through synchronization or by not sharing mutable state at all
99
New cards
API
a defined contract for how software components communicate, exposing operations and their inputs and outputs while hiding the implementation behind them
100
New cards
REST
an API style where resources have URLs and HTTP verbs describe the operation, with each request carrying everything needed to process it