I’ve used Xcode Instruments a few times to check for memory leaks, but I had never explored other templates. After digging around, I realized there isn’t a clear official explanation of each template’s purpose, so I compiled a summary of the templates and their usage.
Apple provides a tutorial on detecting hangs and identifying the cause, which I followed.
Previously, we relied on Sentry to detect hangs, which were only caught alongside crashes, making it hard to distinguish between the two. By using the Time Profiler template in Instruments, it became much easier to analyze the issue since it immediately notifies you when a certain time threshold is exceeded.
I examined all our apps using the appropriate templates and found that it would greatly help improve overall service performance.
In addition, you can use Firebase Performance Monitoring to measure performance. Since Remote Config is a dependency, it gets installed automatically, but you can disable it as needed. This makes it easy to integrate without affecting live services while gaining access to valuable performance insights.
While checking for memory leaks, I reviewed and organized core iOS memory concepts again.
I also watched related WWDC sessions.
Proper memory management boosts app launch speed, improves overall performance, and helps your app (and others) stay longer in memory.
Swift: Deep Copy, Shallow Copy, COW
Note: For reference types to support deep copying, the NSCopying
protocol is typically used.
Before using Instruments or libraries, I listed common cases where memory leaks occur to remain mindful of them during development.
As part of a functional programming course, there was an assignment to implement an ImageLoader using functional concepts. While building it, I realized it would be helpful to package it with features like E-Tag and downsampling so it could be reused across multiple projects.
I organized concepts such as E-Tag, memory cache, disk cache, and downsampling.
NSCache
FileManager
Result+Extension
to handle success and failure as separate flows within a single pipelineI also read various blog posts where developers built their own custom ImageLoaders. One that implemented NSCache
entirely in Swift stood out.
You can see the flow in the diagram below. This will be included in my-swift-package.
graph TD
A("Image Load Request") --> B("Generate Cache Key
URL + Downsampling Options");
B --> C{Check Memory Cache};
C -- Hit --> D{Validate ETag with Network};
C -- Miss --> E{Check Disk Cache};
D -- "✅ 304 (Valid)" --> F([Use Memory Cache Data]);
D -- "🔄 200 (Updated)" --> J[Process New Data];
E -- Hit --> D{Validate ETag};
E -- Miss --> H[Network Request];
D -- "✅ 304 (Valid)" --> I([Use Disk Cache Data]);
I --> I_Save(Save to Memory);
H --> J;
subgraph " "
J --> K(Save to Memory);
K --> L(Save to Disk);
end
F --> Z_Pre(Confirm Final Data);
I_Save --> Z_Pre;
L --> Z_Pre;
Z_Pre -- "Downsampling Option O" --> Z_Downsample(Perform Downsampling);
Z_Pre -- "Downsampling Option X" --> Z_Final(Return UIImage);
Z_Downsample --> Z_Final;
style A fill:#B3E5FC,stroke:#333,stroke-width:2px
style J fill:#FFF9C4,stroke:#333,stroke-width:2px
style H fill:#FFCDD2,stroke:#333,stroke-width:2px
style Z_Final fill:#C8E6C9,stroke:#333,stroke-width:2px