Back to Skills

axiom-objc-block-retain-cycles

verified

Use when debugging memory leaks from blocks, blocks assigned to self or properties, network callbacks, or crashes from deallocated objects - systematic weak-strong pattern diagnosis with mandatory diagnostic rules

View on GitHub

Marketplace

axiom-marketplace

CharlesWiltgen/Axiom

Plugin

axiom

Repository

CharlesWiltgen/Axiom
289stars

.claude-plugin/plugins/axiom/skills/axiom-objc-block-retain-cycles/SKILL.md

Last Verified

January 16, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/CharlesWiltgen/Axiom/blob/main/.claude-plugin/plugins/axiom/skills/axiom-objc-block-retain-cycles/SKILL.md -a claude-code --skill axiom-objc-block-retain-cycles

Installation paths:

Claude
.claude/skills/axiom-objc-block-retain-cycles/
Powered by add-skill CLI

Instructions

# Objective-C Block Retain Cycles

## Overview

Block retain cycles are the #1 cause of Objective-C memory leaks. When a block captures `self` and is stored on that same object (directly or indirectly through an operation/request), you create a circular reference: self → block → self. **Core principle** 90% of block memory leaks stem from missing or incorrectly applied weak-strong patterns, not genuine Apple framework bugs.

## Red Flags — Suspect Block Retain Cycle

If you see ANY of these, suspect a block retain cycle, not something else:
- Memory grows steadily over time during normal app use
- UIViewController instances not deallocating (verified in Instruments)
- Crash: "Sending message to deallocated instance" from network/async callback
- Network requests or animations prevent view controller from closing
- Weak reference becomes nil unexpectedly in a block
- NSLog, NSAssert, or string formatting hiding self references
- Completion handler fires after the view controller "should be gone"
- ❌ **FORBIDDEN** Rationalizing as "It's probably normal memory usage"
  - Memory leaks are never "normal"
  - Apps should return to baseline memory after user dismisses a screen
  - Do not rationalize this as "good enough" or "monitor it later"

**Critical distinction** Block retain cycles accumulate silently. A single cycle might be 100KB, but after 50 screens viewed, you have 5MB of dead memory. **MANDATORY: Test on real device (oldest supported model) after fixes, not just simulator.**

## Mandatory First Steps

**ALWAYS run these FIRST** (before changing code):

```objc
// 1. Identify the leak with Allocations instrument
// In Xcode: Xcode > Open Developer Tool > Instruments
// Choose Allocations template
// Perform an action (open/close a screen with the suspected block)
// Check if memory doesn't return to baseline
// Record: "Memory baseline: X MB, after action: Y MB, still allocated: Z objects"

// 2. Use Memory Debugger to trace the cycle
// Run app, pause at suspec

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
21705 chars