Overview › Lifecycle & State Management

Lifecycle & State Management

Retain cycles, timer leaks, NotificationCenter unbounded observers — major risk.

14 findings in this category · iOS
60
SCORE

Summary

Lifecycle issues are the iOS codebase's biggest concentrated risk: 6 timer-not-invalidated patterns, 21 NotificationCenter observers without removal, retain cycles in completion handlers, and asyncAfter without cancellable WorkItems. The Cookie polling timer fires every 5 seconds for the app lifetime.

Common iOS lifecycle pitfalls

PatternRiskFix
Timer.scheduledTimer not invalidatedStrong ref; controller never releasedtimer?.invalidate() in deinit / viewWillDisappear
NotificationCenter observer not removedObserver retained; app accumulatesCapture token, call removeObserver; or Combine publisher with cancellable
Strong self in escaping closureRetain cycle[weak self] + guard let self else { return }
Non-weak delegateRetain cycle (delegate ↔ owner)weak var delegate: SomeDelegate?
asyncAfter without WorkItemStale callback after dismissalDispatchWorkItem; cancel on disappear. Or Task + cancel.
KVO observer not removedCrash on dealloc with active observerPair every addObserver(_:forKeyPath:) with removeObserver
SwiftUI onAppear work without onDisappear cleanupStale state; leaksMirror onAppear with onDisappear; tie Tasks to view identity

Findings

CRITICAL

Cookie polling timer fires every 5s for app lifetime

Costco/Costco/Application/CookiesManager/CookiesManager.swift:691 — repeating timer not paired with invalidate.
Recommendation: Replace polling with WKHTTPCookieStore observer; or throttle + invalidate on background.
HIGH

21 NotificationCenter observers without removal

Distributed across feature ViewModels.
Recommendation: Capture observer token in init; removeObserver in deinit. Consider NotificationCenter.default.publisher(for: …) + cancellable Set.
HIGH

40+ asyncAfter without cancellation

Closures capture self strongly with no path to cancel.
Recommendation: Standardize on DispatchWorkItem stored on the view controller; or Task + cancel in dismiss path.

Findings in this category

14 shown
Costco iOS · Code Review Report · Generated 2026-05-07 · 88 machine-curated findings