recall · drill
In one line: Cover the blue, say the answer aloud, uncover. Every line is a question you answered “I don’t know”, half-right, or backwards. ! = missed twice / headline gap. Exact names, numbers, lists — the reasoning you already have.
Download PDF Print view LaTeX source
=1.5mm! UIStackView — 4 properties → axis · distribution (sizing along axis) ·
alignment (across axis) · spacing
=1.5mmdistribution values → .fill (default) · .fillEqually · .fillProportionally ·
.equalSpacing · .equalCentering
=1.5mm! Priority values → .required = 1000 · .defaultHigh = 750 ·
.defaultLow = 250
=1.5mmContent hugging → resists growing past intrinsic size; default 250
=1.5mmCompression resistance → resists shrinking below intrinsic size (truncation); default 750
=1.5mmWho loses a tie? → the lower priority stretches/shrinks; nudge ±1 (749, 251) to decide
=1.5mm#1 cause: code view at 0/wrong place → forgot translatesAutoresizingMaskIntoConstraints = false
=1.5mmFacts per view → x, y, width, height — size may come from intrinsic content size
=1.5mmUnsatisfiable constraints → ≥2 contradictory required (1000) → engine breaks one arbitrarily + log; optional (<1000) breaks silently
=1.5mmSelf-sizing cells → rowHeight = .automaticDimension + non-zero estimatedRowHeight +
unbroken top→bottom chain in contentView
=1.5mmSize classes → horizontal/vertical × .compact/.regular; iPhone portrait = compact W,
regular H; iPad = regular/regular
=1.5mm! JSON user_name → userName → (1) enum CodingKeys: String, CodingKey { case
userName = "user_name" } (per key) (2) decoder.keyDecodingStrategy =
.convertFromSnakeCase (blanket) (3) custom init(from:)
=1.5mm! 3 error layers (Reach·Receive·Read) → URLError (transport) → HTTP statusCode not in
200..<300 (not thrown) → DecodingError
(.keyNotFound/.typeMismatch/.dataCorrupted)
=1.5mm! dataTask completion thread → URLSession’s background queue, never main →
DispatchQueue.main.async; call .resume()
=1.5mmasync/await data(from:) → resumes on the caller’s actor — @MainActor caller needs no hop
=1.5mmPinning delegate → urlSession(_:didReceive:completionHandler:) with
URLAuthenticationChallenge → serverTrust → SecTrustEvaluateWithError → SPKI hash →
.useCredential / .cancelAuthenticationChallenge. Default TLS validation: yes
=1.5mmVC order → loadView → viewDidLoad (once) → viewWillAppear → viewDidAppear →
viewWillDisappear → viewDidDisappear
=1.5mmFrame valid from → viewWillLayoutSubviews — not viewDidLoad
=1.5mmApp states → Not Running → Inactive → Active ↔ Inactive → Background → Suspended
=1.5mm! 3 memory tools → Memory Graph Debugger (cycles: who retains whom) · Leaks (unreachable blocks) · Allocations (growth; Mark Generation)
=1.5mmweak vs unowned → weak: Optional, auto-nils, target may die first ·
unowned: non-optional, target outlives self, crash if touched after dealloc
=1.5mmDoes var x: C? break a cycle? → No — ? = nil-ability; weak/unowned = ownership
=1.5mmweak var delegate: P? needs → protocol P: AnyObject
=1.5mm! { [x] in print(x) }, then x = 20 → prints 10: capture list = by-value
snapshot at creation. No list → captures the variable → 20. [obj] copies the pointer
=1.5mm! Copy-on-write → Array Dictionary Set String (+Data): struct wrapping
class storage; isKnownUniquelyReferenced(&storage) — 1 → mutate in place, >1 → copy first.
Your structs: no COW for free
=1.5mm! mutating → lets a struct/enum method change self; caller must be var;
classes never need it; on a let struct → compile error
=1.5mmWhen must it be a class? → identity/shared state · inheritance · ObjC interop · deinit
=1.5mmUnit-test a leak → weak var ref; create SUT in inner scope; after scope
XCTAssertNil(ref)
=1.5mmsome View → opaque type: compiler knows the concrete type; hidden from the caller
=1.5mm@StateObject vs @ObservedObject → view creates & owns (once) vs passed in;
@ObservedObject var vm = VM() resets on parent re-render
=1.5mm@Binding → two-way ref to a parent’s @State, made with $; owns nothing
=1.5mmiOS 17 @Observable → owned → @State; injected → plain property
=1.5mm! Test pyramid → Unit 70% · Integration 20% · UI 10%; inverted = “ice-cream cone”
=1.5mm5 test doubles → Dummy (fills a slot) · Stub (canned answers) · Spy (stub + records calls) · Mock (pre-set expectations, self-verifies) · Fake (working simplified impl, e.g. in-memory)
=1.5mm#expect vs #require → soft (continues) vs hard (throws, stops)
=1.5mmXCTest per-test order → new instance → setUpWithError → setUp → test → teardown
blocks (LIFO) → tearDownWithError → tearDown
=1.5mmLogic lives in (MVC / MVP / MVVM) → Controller / Presenter (View behind a protocol, no UIKit) / ViewModel (View binds, VM has no View ref)
=1.5mmFacade — what + risk → one simple interface over a subsystem (URLSession, Repository);
risk: swells into a god object — delegate, don’t implement
=1.5mmAdapter — textbook iOS → UIViewRepresentable / UIHostingController (UIKit ↔ SwiftUI)
=1.5mmCoordinator solves → a VC that pushes its next screen knows its siblings → not reusable; VC signals intent, Coordinator navigates
=1.5mmRepository read → cache → miss → API → write back → return; caller never knows the source
=1.5mmDI vs DIP → DI = technique (pass deps in); DIP = principle (depend on abstractions)
=1.5mm! Singleton downsides → hidden dependencies · hard to test / state leaks · global mutable state ·
tight coupling (breaks DIP). Impl: static let shared (lazy, thread-safe) + private init
=1.5mm! Strategy vs State → Strategy: client picks the algorithm (stranger) · State: object transitions itself (self)
=1.5mm! Observer’s problem → leaks / retain cycles if not unsubscribed → AnyCancellable,
store(in:), removeObserver
=1.5mm! Command → undo → execute() + undo() (captures state); undo stack: undo = pop, undo(),
push to redo
=1.5mm! Proxy variants → Virtual · Protection · Remote · Caching
(“Very Private Rooms Cache”); lazy var = virtual proxy
=1.5mmInterface: Adapter / Decorator / Facade / Proxy → changes it / keeps + adds behaviour / new simpler one / keeps + gates access
=1.5mm! Template Method → Hollywood principle: “don’t call us, we’ll call you” — base calls
your hooks; e.g. UIViewController lifecycle
=1.5mm! Responder chain direction → up: first responder → superview → VC → window →
UIApplication → app delegate. Hit-testing goes down
=1.5mmMediator → peers talk via a hub: N2 → N links (Coordinator, VM, UINavigationController)
=1.5mmFactory Method vs Abstract Factory → FM: subclass overrides to pick one product ·
AF: one object makes a family. create(type:) switch = Simple Factory
=1.5mm! Decorator vs subclass → N features → 2N subclasses vs N stackable wrappers; Swift:
ViewModifier
=1.5mmBuilder → fixes telescoping init; Swift: default params; recipe object = Director
=1.5mmIterator in Swift → IteratorProtocol.next() -> Element? (nil = end) +
Sequence.makeIterator()
=1.5mmStrategy serves → Open/Closed + Dependency Inversion (not ISP)
=1.5mmS → one, and only one, reason to change
=1.5mmO → open for extension, closed for modification
=1.5mmL → subtypes substitutable for their base types (Square:Rectangle breaks it)
=1.5mm! I → clients should not be forced to depend on methods they do not use
=1.5mm! D → high- and low-level modules both depend on abstractions; abstractions don’t depend on details
=1.5mmErrors → Reach, Receive, Read
=1.5mmTools → Graph = cycles · Leaks = unreachable · Allocations = growing
=1.5mmPriorities → 1000/750/250, spaced by 250 so ±1 breaks ties; 750 = “don’t shrink me”, 250 = “don’t stretch me”
=1.5mmCapture list → a photo: values freeze; references freeze the pointer
=1.5mmOwnership → weak/unowned change ownership; ? only changes nil-ability
=1.5mmStack view → axis = direction · distribution = along · alignment = across · spacing = gaps
=1.5mmAdapter · Decorator · Proxy → changes · adds · gates (a bouncer)