RxSwift Memory Leak Detector
Fast, focused check for RxSwift memory management issues in iOS code.
When to Activate
- •"memory leak", "retain cycle", "dispose bag"
- •"RxSwift memory issues", "check subscriptions"
- •"[weak self]", "memory management"
- •Debugging memory problems or crashes
Quick Check Process
Step 1: Find RxSwift Subscriptions
Use Grep to locate all Observable subscriptions:
- •Pattern:
\.subscribe\( - •Check surrounding code for proper disposal
Step 2: Verify Each Subscription
For every .subscribe(:
- •✅ Has
.disposed(by: disposeBag) - •✅ Uses
[weak self]or[unowned self]in closures - •✅ DisposeBag is a property, not local variable
Step 3: Check Common Patterns
🔴 Pattern 1: Missing Disposal
swift
viewModel.data
.subscribe(onNext: { data in })
// MISSING: .disposed(by: disposeBag)
🔴 Pattern 2: Retain Cycle
swift
viewModel.data
.subscribe(onNext: { data in
self.updateUI(data) // Strong self!
})
🔴 Pattern 3: Local DisposeBag
swift
func loadData() {
let disposeBag = DisposeBag() // Local variable!
// Cancels immediately when function ends
}
Step 4: Generate Report
Focused report with:
- •Critical issues by severity
- •File locations and line numbers
- •Current vs. fixed code
- •Impact assessment
- •Recommended fixes
Search Patterns
Find subscriptions without disposal
code
Pattern: \.subscribe\( Context: Check next 5 lines for .disposed
Find strong self references
code
Pattern: subscribe.*\{[^[]*self\.
Context: -A 3 -B 1
Find local DisposeBag declarations
code
Pattern: let disposeBag = DisposeBag\(\)
Output Format
markdown
# RxSwift Memory Check Report ## Critical Issues: X ### 1. Missing Disposal - MEMORY LEAK **File**: `PaymentViewModel.swift:45` **Risk**: Memory accumulation, eventual crash **Current**: ```swift // Missing disposal
Fix:
swift
.disposed(by: disposeBag)
Impact: [Explanation]
Summary
🔴 Critical: X (memory leaks/retain cycles) ⚠️ Warnings: X (could use weak self)
Files Status
✅ Clean files ⚠️ Files with warnings 🔴 Files with critical issues
code
## DisposeBag Best Practices
✅ **Correct**: Property-level DisposeBag
```swift
class ViewModel {
private let disposeBag = DisposeBag()
}
❌ Wrong: Local DisposeBag
swift
func loadData() {
let disposeBag = DisposeBag() // Cancels immediately!
}
When to Use weak vs unowned
- •Default: Always use
[weak self](safer) - •Rare: Use
[unowned self]only if 100% sure self outlives subscription
Quick Fix Guide
- •Add Missing Disposal:
.disposed(by: disposeBag) - •Add Weak Self:
[weak self]in closure - •Move DisposeBag: To property level
Testing the Fix
Suggest verification:
- •Run Instruments with Leaks template
- •Navigate to/from screens multiple times
- •Check Debug Memory Graph for cycles
- •Verify view controllers deallocate
Reference
Detailed Examples: See examples.md for extensive code samples and scenarios.