I created 2 iOS projects in Xcode:
Project 1:
- 4 targets (main app + 3 app extensions)
- 4 static libraries
- the main app's target dependencies include - 3 app extensions and the 4 libs.
- the main app's binary is linked to all 4 libs
- similarly, each extension is linked to all 4 libs
Project 2:
- 5 targets (main app + 3 app extensions + 1 framework)
- 4 static libraries
- the main app's target dependencies include - 3 app extensions and the framework
- each extension is dependent only on the framework
- the framework's target dependencies include all the 4 static libs
As per my understanding, the app bundle size for Project 2 should be less than that of Project 1, since we eliminate duplicating the static libs for each target by using a framework instead.
However, I have found that the bundle size is more for Project 2 as compared to the bundle size of project 1.
I do not understand, why?
A framework is a fancy wrapper around a shared library. Shared libraries have numerous benefits on Apple platforms:
- They can help reduce build times.
- If the same code is used by multiple programs in your product, like an app and an app extension, putting that code in a shared library can reduce the product’s size.
- If those programs can run simultaneously, a shared library can reduce your product’s memory footprint because only one copy of the code is loaded at a time.
- In some cases — and this is particularly important with Objective-C — using a static library can result in incorrect behaviour at runtime [1].
Oh, and when you bundle a shared library into a framework, there’s one more benefit:
- A framework can have resources used by the shared library’s code.
Having said that, they’re not the right choice in all situations. And that brings me to this:
However, I have found that the bundle size is more for Project 2 as compared to the bundle size of project 1.
I can see why you’d be confused by that result, but the devil is in the details here. For example:
- A shared library has its own overhead, and if these static libraries are small then this overhead might outweigh the benefit.
- It’s easy to embed your shared libraries incorrectly, resulting in multiple copies of the library.
- Other factors, like debug symbols, can significantly affect your results.
- Static libraries are more amenable to dead code elimination. So, if you have a huge amount of shared code but each client only uses a small fraction of it, you’ll definitely win by putting that in a static library.
It sounds like your created a test project to explore this issue. Are you able to share that? If so, please do, because that’ll let us focus on one specific test case.
ps I have a lot of info about linker stuff, including shared libraries and frameworks, in An Apple Library Primer. I assume the terminology defined there, so if I use a term you don’t understand you should check there first.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] If you want to learn more about that, see my responses on this thread.