Mobile Development 18 min read

How to Shrink Your iOS App: Mastering Link Map Analysis and Code Optimization

This article explains how to analyze Link Map files and apply code‑level optimizations—such as removing unused classes, modules, methods, duplicate code, and AB‑test branches—to significantly reduce the binary size of Baidu’s iOS app, providing scripts, commands, and practical tips for each step.

Baidu Geek Talk
Baidu Geek Talk
Baidu Geek Talk
How to Shrink Your iOS App: Mastering Link Map Analysis and Code Optimization

1. Link Map Overview

A Link Map is a text file generated by the linker for a Mach‑O binary. It lists every object file, section, and symbol together with their addresses and sizes, enabling developers to see which parts of the binary occupy the most space.

In Xcode enable Write Link Map File (set to YES) and specify an output path.

Xcode Build Settings – Write Link Map File
Xcode Build Settings – Write Link Map File

The Link Map consists of:

Basic Information : executable path and architecture (e.g., arm64).

Object Files : numbered list of compiled .o files or dylibs.

Sections : offset, size, segment type (TEXT/DATA) and section type.

Symbols : for each method the start address, size, owning object file number, and method name.

# Path: /Users/richard/Desktop/demo/DerivedData/demo/Build/Products/Debug-iphoneos/demo.app/demo
# Arch: arm64

2. Code Optimization Techniques

2.1 Unused‑Class Reduction

Static detection extracts the class list ( __DATA __objc_classlist) and the class‑reference list ( __DATA __objc_classrefs) with otool. The difference yields addresses of classes that are never referenced; these addresses are then symbolised to obtain class names.

otool -v -s __DATA __objc_classlist /path/to/app
otool -v -s __DATA __objc_classrefs /path/to/app

Pros: simple command‑line based.

Cons: cannot detect classes that are referenced but never invoked, and cannot handle reflection‑based usage.

Dynamic detection scans the __DATA segment for the RW_INITIALIZED flag (bit 1<<29) in the class_rw_t structure. Classes whose flag is not set have never been initialised at runtime.

#define RW_INITIALIZED (1<<29)
bool isInitialized(class_rw_t *rw) { return rw->flags & RW_INITIALIZED; }

Pros: no source changes, works for all builds.

Cons: limited to Objective‑C; does not cover Swift or C/C++.

2.2 Unused‑Module Reduction

For each module (library) compute the ratio of unused classes:

unused_ratio = (number_of_unused_classes / total_classes) * 100

If the ratio is 100 % the module can be removed entirely; if it exceeds 90 % a selective clean‑up is performed.

2.3 Unused‑Method Reduction

Combine the selector reference list ( __objc_selrefs) with method definitions extracted from the Link Map. The set difference yields methods that are never called. Accuracy is typically low (≈40 %) because of dynamic dispatch, categories and protocol conformance.

2.4 Duplicate‑Code Elimination

PMD/CPD scans Objective‑C source for duplicated code blocks.

brew install pmd
pmd cpd --files /path/to/source --minimum-tokens 70 --language objectivec --encoding UTF-8 --format xml > repeat.xml

The generated XML lists each duplication with file paths, line numbers and the duplicated fragment, enabling refactoring or extraction of common utilities.

2.5 Tool‑Method Consolidation

Parse the Link Map to find duplicate Category implementations and merge them into a shared utility library. Example Python helper:

def get_files_map(base_link_map_file):
    with open(base_link_map_file, 'rb') as f:
        reach_files = 0
        files_map = {}
        for line in f:
            line = line.decode('utf-8', errors='ignore')
            if line.startswith('#'):
                if line.startswith('# Object files:'):
                    reach_files = 1
            else:
                if reach_files:
                    idx = line.find(']')
                    if idx != -1:
                        symbol = {'file': line[idx+2:-1]}
                        key = int(line[1:idx])
                        files_map[key] = symbol
    return files_map

2.6 AB‑Test Code Solidification

AB experiments generate code branches that may become obsolete. The workflow:

Fetch the list of switches that have been permanently enabled.

Search the codebase for those switch strings (Obj‑C regex @"(.*?)", Swift regex "(.*?)").

Remove dead branches and keep only the active code.

#define kFaceverifyResourceOptimizeABTestKey @"face_verify_resource_optimize_enable"

3. Practical Scripts

Python script to map object files to classes from a Link Map:

def find_class(base_link_map_file):
    with open(base_link_map_file, 'rb') as f:
        reach_files = 0
        files_map = {}
        for line in f:
            line = line.decode('utf-8', errors='ignore')
            if line.startswith('#'):
                if line.startswith('# Object files:'):
                    reach_files = 1
            else:
                if reach_files:
                    idx = line.find(']')
                    if idx != -1:
                        tmpfile = line[idx+2:-1]
                        file = tmpfile.split('/')[-1]
                        framework_idx = file.find('(')
                        if framework_idx != -1:
                            framework = file[:framework_idx]
                            classname = file[framework_idx+1:-1]
                            files_map.setdefault(framework, []).append(classname)
    return files_map

4. Outcome

Link Map analysis combined with the techniques above identified roughly 20 MB of removable code in the Baidu iOS app; about 8 MB have been shipped, with the remainder pending further automation and validation.

References

PMD official site: https://pmd.github.io/

PMD CPD usage: https://pmd.sourceforge.io/pmd-5.5.1/usage/cpd-usage.html

Apple XNU source: https://github.com/apple/darwin-xnu

Objective‑C runtime source: https://github.com/apple-oss-distributions/objc4/tags

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Package SizeiOSMach-OCode Optimizationstatic analysisLink Map
Baidu Geek Talk
Written by

Baidu Geek Talk

Follow us to discover more Baidu tech insights.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.