What does dyld do, and how do static and dynamic linking change launch?
Predict first
Which has the larger launch-time cost, other things equal?
// A: one dynamic framework with 500 classes
// B: ten dynamic frameworks with 50 classes each
- A
- B
Mental model. Loading a binary is unpacking boxes. Every box (dynamic library) has to be opened and its labels updated, so one big box is faster than fifty small ones.
dyld is the dynamic linker. It reads the binary’s load commands, maps each dependent dylib (your own frameworks plus system libraries), then performs rebase (adjust internal pointers when the image is loaded at a random address) and bind (fill in pointers to symbols in other libraries), sets up Objective-C and Swift runtime metadata, and runs initialisers. System libraries are pre-linked into a shared cache, so they cost far less than yours. Newer toolchains use chained fixups to make the fix-up step faster.
Your costs scale with how much dyld has to do: the number of dynamic frameworks (each is a file to map and a set of fix-ups), the number of Objective-C classes and categories to register, and the amount of pointer data to adjust. Linking code statically into the app removes per-library mapping, which is why many small dynamic frameworks are slower to launch than one larger one, and why Xcode offers mergeable libraries to get the build-time benefits of separate frameworks with launch-time merging. The trade-off is binary size and the loss of independent updates; keep app-owned code in as few dynamic images as practical.
Each dynamic framework adds mapping and fix-up work, so splitting the same code across more images costs more at launch.
Common traps
- Splitting the app into many dynamic frameworks for tidiness. Each one adds launch work. Use static libraries or mergeable libraries.
- Assuming system frameworks cost the same as yours. They live in the shared cache and are far cheaper to load.
They might follow up with
- How do you list what an app links?
otool -L App, or the image list in the debugger. - What are rebase and bind? Rebase fixes pointers inside the image for its load address; bind resolves pointers to symbols outside it.
Related questions
- 6.4.1 Walk through what happens from tapping the icon to the first frame.
- 6.4.3 Your app launches slowly. How do you find out why and what do you cut?
- 4.8.1 How do Swift and Objective-C see each other: bridging header, umbrella header, and the -Swift.h file?
← Walk through what happens from tapping the icon to the first frame. Your app launches slowly. How do you find out why and what do you cut? →