krzysztofzablocki/LifetimeTracker
Find retain cycles / memory leaks sooner.
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2mo ago
- ✓29+ active contributors
- ✓Distributed ownership (top contributor 46% of recent commits)
Show 3 more →Show less
- ✓MIT licensed
- ✓Tests present
- ⚠No CI workflows detected
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/krzysztofzablocki/lifetimetracker)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/krzysztofzablocki/lifetimetracker on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: krzysztofzablocki/LifetimeTracker
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/krzysztofzablocki/LifetimeTracker shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 2mo ago
- 29+ active contributors
- Distributed ownership (top contributor 46% of recent commits)
- MIT licensed
- Tests present
- ⚠ No CI workflows detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live krzysztofzablocki/LifetimeTracker
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/krzysztofzablocki/LifetimeTracker.
What it runs against: a local clone of krzysztofzablocki/LifetimeTracker — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in krzysztofzablocki/LifetimeTracker | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 96 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of krzysztofzablocki/LifetimeTracker. If you don't
# have one yet, run these first:
#
# git clone https://github.com/krzysztofzablocki/LifetimeTracker.git
# cd LifetimeTracker
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of krzysztofzablocki/LifetimeTracker and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "krzysztofzablocki/LifetimeTracker(\\.git)?\\b" \\
&& ok "origin remote is krzysztofzablocki/LifetimeTracker" \\
|| miss "origin remote is not krzysztofzablocki/LifetimeTracker (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "Example/LifetimeTracker/AppDelegate.swift" \\
&& ok "Example/LifetimeTracker/AppDelegate.swift" \\
|| miss "missing critical file: Example/LifetimeTracker/AppDelegate.swift"
test -f "Example/LifetimeTracker/ViewController.swift" \\
&& ok "Example/LifetimeTracker/ViewController.swift" \\
|| miss "missing critical file: Example/LifetimeTracker/ViewController.swift"
test -f "ExampleObjC/ExampleObjC/AppDelegate.m" \\
&& ok "ExampleObjC/ExampleObjC/AppDelegate.m" \\
|| miss "missing critical file: ExampleObjC/ExampleObjC/AppDelegate.m"
test -f "Configs/LifetimeTracker.plist" \\
&& ok "Configs/LifetimeTracker.plist" \\
|| miss "missing critical file: Configs/LifetimeTracker.plist"
test -f "Example/Podfile" \\
&& ok "Example/Podfile" \\
|| miss "missing critical file: Example/Podfile"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 96 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~66d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/krzysztofzablocki/LifetimeTracker"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
LifetimeTracker is a runtime memory leak detector for iOS/macOS that surfaces retain cycles during development by tracking object lifetimes, displaying them via an on-screen dashboard (bar or circular UI). Unlike Facebook's FBRetainCycleDetector which relies on Objective-C runtime introspection, LifetimeTracker works with pure Swift classes and doesn't require complex automatic magic. Modular structure: core tracking logic in main package, Example/ contains a runnable iOS app demonstrating both UI styles (bar and circular), Configs/ holds plist-based configuration for the library and tests. Framework is consumed as a pod/SPM dependency rather than a monorepo pattern.
👥Who it's for
iOS/macOS developers building Swift or Objective-C codebases who want to catch memory leaks during feature development (not sporadically via Instruments). ViewControllers and ViewModel authors particularly benefit by tracking key actors in their apps to prevent issues before release.
🌱Maturity & risk
Mature and actively maintained: distributed via CocoaPods/Carthage/SPM, demonstrates substantial Swift codebase (94K lines), includes example app with both bar and circular UI styles, and supports both Swift and Objective-C. No recent commit visibility in data provided, but the polished API and multiple integration paths suggest production readiness.
Low risk: single-author maintenance (krzysztofzablocki) is a known risk, no visible test suite or CI configuration in top-level files suggests test coverage opacity. However, debug-only activation (#if DEBUG) means production builds are unaffected. Requires understanding of when to track objects (manual setup per-class), not automatic—misconfiguration won't detect all leaks.
Active areas of work
Cannot determine from file list alone (no git history provided), but the Example app with both visual styles and multi-language support (Swift + Objective-C) indicates active polish. The README mentions iOS 13+ SceneDelegate integration, suggesting ongoing modernization.
🚀Get running
Check README for instructions.
Daily commands:
After pod install, open Example/Example.xcworkspace in Xcode. Select the LifetimeTracker-Example scheme and build for iOS 13+. The app will launch with the LifetimeTracker dashboard visible (bar or circular style, configurable at setup in AppDelegate/SceneDelegate).
🗺️Map of the codebase
Example/LifetimeTracker/AppDelegate.swift— Main entry point for the Swift example app demonstrating LifetimeTracker integration and lifetime monitoring setup.Example/LifetimeTracker/ViewController.swift— Primary example implementation showing how to track object lifetimes and detect retain cycles in practice.ExampleObjC/ExampleObjC/AppDelegate.m— Objective-C entry point proving LifetimeTracker works across Swift and ObjC codebases without runtime magic.Configs/LifetimeTracker.plist— Core configuration file controlling LifetimeTracker behavior, thresholds, and detection settings.Example/Podfile— Dependency manifest showing LifetimeTracker integration into a real iOS project via CocoaPods.Example/Tests/Tests.swift— Test suite validating LifetimeTracker's detection accuracy and core memory tracking functionality.
🧩Components & responsibilities
- LifetimeTracker Core (Swift, Objective-C bridging) — Main API entry point; initializes monitoring system, loads config, and registers objects for tracking
- Failure mode: Fails silently if plist config missing; defaults to permissive thresholds; visual UI may not appear if overlays disabled
- Lifetime Monitor (ARC observation, deinit hooks) — Continuously observes reference counts and lifecycle events for registered objects; compares against plist thresholds
- Failure mode: Misses leaks if object never deallocates (indefinite retention); cannot detect leaks in unregistered objects
- Configuration Manager (plist) (PropertyList, UserDefaults) — Loads detection thresholds, UI style (bar/circular), and sensitivity settings from bundle plists
- Failure mode: Misconfigured thresholds cause false positives/negatives; missing plist falls back to unsafe defaults
- UI Overlay (Visual Feedback) (UIKit (or SwiftUI adapters), CADisplayLink) — Renders real-time bar or circular progress indicators showing object count and lifetime warnings
- Failure mode: Overlay may not appear if disabled; visual jank if updates block main thread
🔀Data flow
AppDelegate (App Launch)→LifetimeTracker Core— Initialization call triggers config load and monitoring system startupViewController/Business Logic→LifetimeTracker Core— Objects to be monitored are registered via explicit API callsLifetimeTracker.plist (Bundle)→Configuration Manager— Detection thresholds, UI styles, and sensitivity levels are loaded at init timeObject Lifetime Events (allocation/deallocation)→Lifetime Monitor— ARC and deinit observers feed reference count changes into detection logicLifetime Monitor (detection logic)→UI Overlay— When thresholds exceeded, visual alert is triggered (bar or circular style)Lifetime Monitor→Console/Logging— Warnings and detailed leak diagnostics logged for developer review
🛠️How to make changes
Integrate LifetimeTracker into a New Swift Project
- Add LifetimeTracker to your Podfile dependency list (or manually include the framework) (
Example/Podfile) - Initialize LifetimeTracker in your AppDelegate.swift application(_:didFinishLaunchingWithOptions:) method (
Example/LifetimeTracker/AppDelegate.swift) - Create a configuration plist file matching LifetimeTracker.plist with your detection thresholds (
Configs/LifetimeTracker.plist) - Wrap objects you want to track by calling the tracker's monitoring API in your ViewControllers (
Example/LifetimeTracker/ViewController.swift)
Add LifetimeTracker to an Objective-C Project
- Add LifetimeTracker pod or framework to your ExampleObjC/Podfile (
ExampleObjC/Podfile) - Import and initialize LifetimeTracker in AppDelegate.m's application:didFinishLaunchingWithOptions: (
ExampleObjC/ExampleObjC/AppDelegate.m) - Use LifetimeTracker's Objective-C APIs to track object lifetimes in your ViewControllers (
ExampleObjC/ExampleObjC/ViewController.m)
Configure Retain Cycle Detection Thresholds
- Open the LifetimeTracker.plist configuration file in your project (
Configs/LifetimeTracker.plist) - Adjust detection sensitivity, warning thresholds, and tracked object categories to match your app's patterns (
Configs/LifetimeTracker.plist) - For test environments, create an alternate config file matching the pattern in LifetimeTrackerTests.plist (
Configs/LifetimeTrackerTests.plist)
🔧Why these technologies
- CocoaPods for dependency management — Standard iOS package management enabling easy integration into existing Swift and Objective-C projects; no custom build system complexity.
- Plist configuration files (LifetimeTracker.plist) — Native iOS config format allows developers to adjust detection sensitivity without code changes; supports test vs. production variants.
- Reference counting observation (not reflection/objc runtime magic) — Works reliably with pure Swift classes, avoiding the limitations of FBRetainCycleDetector; clean, language-agnostic approach.
- Visual overlay UI (bar + circular styles) — Immediate developer feedback during feature development; surfacing issues in real-time reduces cost of investigation vs. post-hoc Instruments analysis.
⚖️Trade-offs already made
-
Manual object registration instead of automatic bytecode instrumentation
- Why: Simplifies implementation and makes it compatible with both Swift and Objective-C without runtime magic.
- Consequence: Developers must explicitly opt-in to tracking; reduced automation means some leaks may be missed if not registered.
-
Config-driven thresholds (plist) instead of hardcoded detection logic
- Why: Allows teams to tune sensitivity per project and environment without code changes.
- Consequence: Requires upfront config tuning and separate test/prod configs; misconfiguration can lead to false positives or false negatives.
-
In-app visual alerts instead of CI/CD gate or build failure
- Why: Surfaces issues immediately during development; non-blocking for iteration speed.
- Consequence: Does not enforce cleanup in CI; relies on developer discipline to act on warnings.
🚫Non-goals (don't propose these)
- Does not perform automatic SwiftUI/UIKit view lifecycle detection
- Does not instrument bytecode or use reflection for discovery
- Does not integrate into Xcode's main debugger UI or memory graph
- Does not enforce memory constraints at app/system level
- Does not provide historical leak database or long-term analytics
⚠️Anti-patterns to avoid
- Manual object registration overhead —
Example/LifetimeTracker/ViewController.swift, ExampleObjC/ExampleObjC/: undefined
🪤Traps & gotchas
Manual tracking requirement: LifetimeTracker does NOT automatically detect all object lifetimes—you must explicitly track key actors by calling the tracking API in their init/deinit. Debug-only activation: the setup code uses #if DEBUG conditional compilation, so attempting to use it in Release builds will result in no-op. Swift vs Objective-C parity: Objective-C interop requires proper bridging headers; incorrect setup may miss legacy ObjC class leaks. Storyboard coupling: the example app relies on XIB/storyboard files; SwiftUI migration would require rewriting the dashboard UI layer.
🏗️Architecture
💡Concepts to learn
- Retain Cycle / Circular Reference — LifetimeTracker's entire purpose is surfacing these—understanding why object A holding a strong reference to B while B holds one back prevents deallocation is foundational.
- Automatic Reference Counting (ARC) — LifetimeTracker operates within ARC's memory model; understanding retain counts and lifecycle transitions (init → deinit) is necessary to predict what the tracker reports.
- Weak and Unowned References — The standard Swift solutions to retain cycles; LifetimeTracker helps catch instances where developers forgot to apply these, making this a critical concept for users.
- Object Lifetime Tracking — LifetimeTracker's core mechanism—manually instrumenting init/deinit to record when objects are created/destroyed, enabling detection of objects that should have been deallocated but weren't.
- Escape Closures and Capture Lists — A common source of retain cycles in Swift; closures that escape a function scope can capture
selfstrongly unless explicitly marked[weak self]or[unowned self]—the tool helps identify these patterns. - Delegation Pattern and Retain Cycles — Delegates are commonly tracked as strong references by accident; LifetimeTracker helps catch when a parent holds a strong reference to a delegate that also holds one back.
🔗Related repos
facebook/FBRetainCycleDetector— Direct competitor solving the same memory leak detection problem, but relies on Objective-C runtime introspection and cannot detect pure Swift retain cycles—LifetimeTracker's key differentiator.square/leakcanary— Android equivalent for detecting memory leaks at runtime with on-screen notifications; shows the cross-platform demand for developer-friendly leak detection outside Instruments.krzysztofzablocki/Sourcery— Same author's meta-programming tool for code generation; many LifetimeTracker users generate boilerplate tracking code using Sourcery to reduce manual API calls.apple/swift-memory-tools— Apple's native memory introspection APIs; LifetimeTracker complements rather than replaces them by providing continuous dev-time feedback vs. sporadic Instruments sessions.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for LifetimeTracker core tracking logic
The repo has Example/Tests/Tests.swift but appears to lack comprehensive unit tests for the core LifetimeTracker framework itself. Given this is a memory leak detection tool, robust tests validating that tracking correctly identifies object lifetimes, handles weak references, and detects potential retain cycles would be critical. This would increase contributor confidence in changes and catch regressions early.
- [ ] Create Sources/LifetimeTracker/Tests/ directory with test files for core tracking logic
- [ ] Add tests validating object registration/deregistration in the tracker
- [ ] Add tests for weak reference handling and cycle detection
- [ ] Add tests covering both Swift and Objective-C object lifetime tracking
- [ ] Integrate tests into build pipeline via Example project scheme
Add GitHub Actions CI workflow for automated testing on PR
The repo lacks a visible CI/CD pipeline (no .github/workflows/ detected). For a memory safety tool, automated testing on every PR is critical to prevent regressions. A workflow that builds the Example project, runs tests, and validates against multiple iOS SDK versions would ensure quality.
- [ ] Create .github/workflows/ci.yml with iOS build and test job
- [ ] Configure workflow to test against multiple Xcode versions
- [ ] Add step to build Example/Example.xcworkspace with LifetimeTracker pod
- [ ] Add step to run Example/Tests/Tests.swift
- [ ] Configure workflow to report test coverage metrics
Add Objective-C integration tests and documentation in ExampleObjC
The repo emphasizes Objective-C support (ExampleObjC/ exists) but there's minimal visibility into whether the ExampleObjC project is fully tested or documented. Adding comprehensive integration tests demonstrating LifetimeTracker usage with Objective-C patterns (property tracking, dealloc validation, block capture detection) with corresponding docs would validate the Objective-C claim and help contributors understand framework behavior.
- [ ] Add ExampleObjC/Tests/ directory with ObjC integration tests
- [ ] Create tests validating tracking of ObjC instance variables and properties
- [ ] Add tests for __weak reference handling in Objective-C blocks
- [ ] Create ExampleObjC/TESTING.md documenting ObjC-specific test patterns
- [ ] Ensure ExampleObjC.xcodeproj tests are runnable in CI
🌿Good first issues
- Add unit tests for the core LifetimeTracker tracking API (currently no test suite visible in top-level files). Start by creating a new test target that verifies object deinit is properly tracked when instances are deallocated.
- Document the retention graph—add a README section or inline comments explaining how to interpret the tracked groups and what 'EntriesGroup' represents. The current docs show usage but not the mental model.
- Extend the Example app's ViewController.swift with 5-10 deliberate retain cycle patterns (circular delegates, block captures, unowned misuse) that the dashboard should flag, then verify they're caught correctly.
⭐Top contributors
Click to expand
Top contributors
- @krzysztofzablocki — 46 commits
- [@Hans Seiffert](https://github.com/Hans Seiffert) — 9 commits
- @ls-philippe-casgrain — 6 commits
- @tschob — 6 commits
- @bluemon82 — 3 commits
📝Recent commits
Click to expand
Recent commits
36844ff— [ISSUE-98] Fix not respecting user dismissal (#102) (wedkarz)30d3478— [ISSUE-98] Fix for Lifetime tracker blocks UI when closed (#99) (wedkarz)fccc98a— Fix leak detection and warning (#94) (MontakOleg)f5c25c5— chore: cleanup (krzysztofzablocki)1cc54d8— fix: text display issue on cocoapod installation (#91) (xing3523)f0aa77b— Update README.md (krzysztofzablocki)0f62a7b— fix: not appearing initially (krzysztofzablocki)2bfcdbf— Add color customization to LifetimeTrackerDashboardIntegration (#87) (acosmicflamingo)bceb84c— make track function public in LifetimeTracker class (#84) (bohan-v)8dff4a7— pods 1.8.1 (krzysztofzablocki)
🔒Security observations
The LifetimeTracker repository has a relatively good security posture as a development tool focused on memory leak detection. The main concerns are operational/configuration issues rather than code vulnerabilities: (1) CocoaPods dependencies are committed to the repository, increasing size and potential for tampering, (2) no explicit dependency security scanning visible, and (3) missing security documentation. The codebase itself, being a memory debugging tool without network access or data handling, presents minimal attack surface. No hardcoded secrets, injection risks, or critical misconfigurations were identified in the visible file structure.
- Low · Pods Directory Committed to Repository —
Example/Pods, ExampleObjC/Pods. The Example/Pods and ExampleObjC/Pods directories appear to be committed to the repository. CocoaPods dependencies should typically be managed via Podfile and Podfile.lock only, with Pods/ added to .gitignore. This increases repository size and can lead to outdated or tampered dependencies. Fix: Add 'Pods/' to .gitignore and remove committed Pods directories from git history. Users should run 'pod install' to fetch dependencies. - Low · Missing or Incomplete .gitignore —
.gitignore. While a .gitignore file exists, the presence of committed Pods directories suggests it may not be properly configured. Build artifacts and dependency folders should be excluded. Fix: Ensure .gitignore includes: Pods/, *.xcworkspace/xcuserdata/, DerivedData/, build/, and other Xcode-generated files. - Low · No Visible Dependency Verification —
Example/Podfile, Example/Podfile.lock, ExampleObjC/Podfile, ExampleObjC/Podfile.lock. The repository structure shows Podfile and Podfile.lock files, but no evidence of dependency pinning verification or security scanning (e.g., no Podfile.lock hash verification or CocoaPods security plugins). Fix: Regularly audit CocoaPods dependencies using tools like 'pod install --repo-update' with security checks. Consider using dependency scanning tools compatible with CocoaPods. - Low · Lack of Security Documentation —
Repository root. No visible SECURITY.md, security policy, or vulnerability disclosure guidelines in the repository structure. Fix: Create a SECURITY.md file documenting how users should report security vulnerabilities and your security practices.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.