Here we are going to see one of the most overlooked concepts in iOS development. Static libraries and dynamic libraries and how it impacts your app. Let’s dive in,
What is a Static Library?
When an app is linked with a library(Framework) using a static linker, the code that the app uses is copied to the generated executable file. A static linker collects compiled source code, known as object code, and library code into one executable file that is loaded into memory in its entirety at runtime. The kind of library that becomes part of an app’s executable file is known as a static library.— Apple Documentation
As the apple documentation clearly says, when an app is launched, the app’s executable file — which includes the binary of the static libraries with which it was linked — is loaded into the app’s address space.
So ideally what happens is that the app produces a large executable file resulting in slow launch times and large memory footprint.
What is a Dynamic Library?
Dynamic libraries are not statically linked into client apps; they don’t become part of the executable file. Instead, dynamic libraries can be loaded (and linked) into an app either when the app is launched or as it runs. — Apple Documentation
In the case of dynamic linking the app loads library code into its address space when it’s actually needed, either at launch time or at runtime.
The loading of these dynamic libraries into memory is done using a special framework called the dynamic loader
How to specify a library as Static or Dynamic?
Specifying a library as static or dynamic is relatively simple. Select your framework target -> Build Setting -> Search “Macho” in the search field, then you can select from the drop down to make your library as static or dynamic.
Static or Dynamic library in action
Here we are going to see a practical example for how a static library and dynamic library affects the executable size of the host app. On clicking show package contents of the archived file of the host app, we can observe the below
- Static library: Keeping the Macho of the framework as ‘Static Library’ and embedding in to host app, the library code is copied into the host app’s executable and the host app executable size is 680 KB.
Host app executable + statically linked library code = 680 KB
2. Dynamic Library: Keeping the Macho of the framework as ‘Dynamic Library’ and embedding in to host app, the host app doesn’t copy the library code into its executable and the app’s executable size is independent of the library.
The host app executable size is now 432 KB.
Note: Depending on your need whether you need to access the resources of your library such as storyboards, image files, and localized strings, you can either embed or do not embed the static library to your host app. In the case of dynamic linking you need to embed as the library needs to be in your bundle for the dynamic loader to identify the modules. Embedding affects your .ipa size but does not affect executable binary size. Executable binary size is affected only by static or dynamic linking.
Which to choose Static or Dynamic?
Based on the documentation, Apple strongly suggests the usage of Dynamically linked library and to avoid static linkage due to the following reasons,
Static linkers pros:
- Guarantees that all the code needed to run are in place since they are linked to host app at compile time and generated as a single executable file.
Static linkers cons:
- Static libraries increases the executable file size of an app
- Applications with large executables suffer from slow launch times and large memory footprints
- When a static library is updated, the entire host app has to be updated with the latest version as the host app’s executable is coupled to the library’s binary
Dynamic linkers pros:
- Host app loads code into its address space when it’s actually needed, either at launch time or at runtime
- They also allow apps to delay loading libraries with special functionality only when they’re needed instead of at launch time. This feature contributes further to reduced launch times and efficient memory use.
- Reduced size of an app’s executable file and minimizing its use of memory once it’s launched make the app launch faster and use less memory once it’s launched
- Doesn’t require app developers to recompile the host apps when there is an upgrade in the library.
- Dynamically linked modules can be initialized when they are loaded and can perform clean-up tasks when the client app terminates normally.
Dynamic linkers cons:
- Adding a lot of dynamic libraries into the project could be a problem causing a performance delay during start.
- If you miss to embed you will end up in runtime error
The Apple recommendation is using dynamic libraries instead of static libraries reduces both the file size and initial memory footprint of the apps that use them. But at the same time care has to be taken not to use too many dynamic libraries.
Please reach me out at firstname.lastname@example.org is case of any queries. Happy Coding…!