- Use `@autoreleasepool { }` blocks in loops that create many temporary objects to reclaim memory before the runloop's default autorelease pool drains.
- Use `NSCache` for in-memory caching of expensive computed objects — it automatically evicts entries under memory pressure unlike `NSMutableDictionary`.
- Use `dispatch_async` with `dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)` for background work and `dispatch_get_main_queue()` for UI updates.
- Use `CGImageRef` and Core Graphics for drawing-intensive paths instead of `UIImage` compositing — Core Graphics avoids UIKit overhead.
- Use `NSOperationQueue` with `maxConcurrentOperationCount` for controlling parallelism in batch operations — prefer it over raw GCD for cancellable tasks.
- Use `drawRect:` sparingly — prefer `CALayer` compositing with `shouldRasterize` and `rasterizationScale` for static layer content.
- Profile with Instruments (Time Profiler, Allocations, Leaks) before optimizing — measure actual hotspots before rewriting code.