Startup optimization It is in the cold startup phase of the APP. The initialization of various SDKS and the configuration initialization of our APP are counted as startup items. Generally we will heap they direct the AppDelegate – (BOOL) application: (UIApplication *) application didFinishLaunchingWithOptions: (NSDictionary *) the launchOptions method. At the beginning of the project, it was fine. Once there were more iterations of the project, the startup of various functions and SDKS increased sharply. At this time, we would find that the cold APP startup was slow, which greatly affected the user experience.
The knowledge point that boot item optimization governance needs to use has:
- Mach-O
- Compile the instruction
__attribute__
Mach-O
Mach-o stands for Mach Object file format, which is a file format for executable files, Object code, dynamic libraries, and kernel dumps. As an alternative to the A.out format, Mach-O provides greater scalability and speeds up access to information in symbol tables. [Excerpt from Baidu Encyclopedia]
In short, Mach-o is an executable file on Mac/iOS. When we compile an iOS project, we usually produce an xxx.app file. When we right-click on the package contents, we can find a Mach-o file with the name xx.
Command otool -l XXX to view the contents of the Mach -o file:
Below is an excerpt of the contents of the Mach-o file
EasyLaunch:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
0xfeedfacf 16777223 3 0x00 2 22 3344 0x00200085
Load command 0
cmd LC_SEGMENT_64
cmdsize 72
segname __PAGEZERO
vmaddr 0x0000000000000000
vmsize 0x0000000100000000
fileoff 0
filesize 0
maxprot 0x00000000
initprot 0x00000000
nsects 0
flags 0x0
Load command 1
cmd LC_SEGMENT_64
cmdsize 872
segname __TEXT
vmaddr 0x0000000100000000
vmsize 0x0000000000004000
fileoff 0
filesize 16384
maxprot 0x00000005
initprot 0x00000005
nsects 10
flags 0x0
Section
sectname __text
segname __TEXT
addr 0x0000000100001540
size 0x0000000000000c43
offset 5440
align 2^4 (16)
reloff 0
nreloc 0
flags 0x80000400
reserved1 0
reserved2 0
...
Copy the code
attribute
__attribute__ is a compilation instruction that specifies error checking during declaration and advanced optimization features.
Its position constraint is: placed at the end of the declaration “;” before
Attribute writing features: The attribute is preceded by two underscores, followed by a pair of parentheses, which contain the corresponding __attribute__ parameter.
The format of the attribute syntax is: attribute ((attribution-list))
Functions tagged attribute__((used)) are tagged in the target file to prevent the linker from removing unused sections.
Functions or variables that mark __attribute__((section(“new_section”))) are put into the new_section of the DATA segment by the compiler, not into the TEXT segment.
The principle of
By __attribute__, the function pointer that defines the startup item is placed under _easy_x in the DATA segment, and the content under the corresponding section is read at the appropriate time when the project is running, and the execution function can achieve the optimized governance of the startup item.
implementation
Start function entry definition:
#define EASY_REGISTER_LAUNCH_FUNCATION(key) __EASY_REGISTER_LAUNCH_FUNCATION(key)
#define __EASY_REGISTER_LAUNCH_FUNCATION(key) \
static void __EASY_REGISTER_LAUNCH_##key(void); \
__attribute__((used, section("__DATA," "_easy_" #key))) \
static const void * __EASY__##key = __EASY_REGISTER_LAUNCH_##key; \
static void __EASY_REGISTER_LAUNCH_##key(void) \
Copy the code
The startup function is used, implemented in a.m file:
EASY_REGISTER_LAUNCH_FUNCATION(LaunchSection_didFinishLaunching) {NSLog(@" execute LaunchSection_didFinishLaunching"); }Copy the code
After compilation, you can see how many sections there are in the Mach-o file:
Execute the specified boot option:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[EasyLaunch executeWithSection:LaunchSection_didFinishLaunching];
return YES;
}
Copy the code
Read the implementation of the specified starter function pointer:
#ifndef __LP64__
#define mach_header_c mach_header
#else
#define mach_header_c mach_header_64
#endif
void _executeWithSection(long section) {
Dl_info info;
if (dladdr(&_executeWithSection, &info)) {
struct mach_header_c *machHeader = (struct mach_header_c *)info.dli_fbase;
NSString *s = [NSString stringWithFormat:@"_easy_%zd",section];
#ifndef __LP64__
unsigned long size = 0;
uintptr_t *data = (uintptr_t *)getsectiondata(machHeader, "__DATA", s.UTF8String, &size);
if (data == NULL) {
return;
}
int count = (int)(size / sizeof(void *));
for (int i = 0; i < count; ++i) {
void (*function)(void) = (void (*)(void))data[i];
(function)();
}
#else
const struct section_64 * section64 = getsectbynamefromheader_64(machHeader, "__DATA", s.UTF8String);
if (section64 == nil) {
return;
}
uint16_t step = sizeof(void *);
for (uint16_t offset = section64->offset; offset < section64->offset + section64->size; offset += step) {
void (**function)(void) = (void (**)(void))((uint64_t)machHeader + offset);
(*function)();
}
#endif
}
}
Copy the code
Attached source code: EasyLaunch
Reference:
Meituan Takeout iOS App cold start management