What should an app do on a memory warning, and how reliable is the warning?
Predict first
Does this compile?
import Foundation
let source = DispatchSource.makeMemoryPressureSource(eventMask: [.warning, .critical], queue: .main)
source.setEventHandler { print("pressure") }
source.resume()
- Yes
- No
Predict first
Can a memory warning be relied on to arrive before the app is killed for memory?
// A: yes, always
// B: no, it is advisory and a sudden spike can skip it
- A
- B
Mental model. A fire alarm that sometimes rings and sometimes does not. You tidy up when it rings, but you design the building so a fire never needs the alarm.
When free memory gets low the system sends a memory warning: didReceiveMemoryWarning on view controllers, UIApplication.didReceiveMemoryWarningNotification for the app, and (outside UIKit) a memory-pressure dispatch source (DispatchSource.makeMemoryPressureSource) with warning and critical events. The right response is to release what you can rebuild: image and data caches, decoded assets for screens that are not visible, preloaded views, and anything you can fetch or recompute. NSCache evicts by itself; hand-written caches must be cleared.
Do not treat the warning as a promise. It is advisory and may not arrive: a sudden spike (decoding a huge image, parsing a big payload) can push the process over its limit with no warning, and a backgrounded app can be killed outright. So the warning is a courtesy to reduce pressure, not a safe point. Keep your peak memory low by design (stream, downsample, work in chunks), and make caches self-limiting. Test with the Xcode “Simulate Memory Warning” command and by profiling the peak, not only the steady state.
A memory-pressure source is a dispatch source with .warning and .critical events, and works outside UIKit.
The warning is a courtesy. The kernel can terminate a process that exceeds its limit without notifying it first.
Common traps
- Doing expensive work in
didReceiveMemoryWarning. You are already under pressure, so only free memory there. - Relying on the warning to avoid being killed. A large, sudden allocation skips it.
They might follow up with
- What is the pressure level “critical” for? It signals the system is about to start killing; release as much as you can.
- How do you observe memory use? The Xcode memory gauge,
os_proc_available_memory(), and Instruments, as covered in the memory section.