爲了使用二進制重排優化應用的啓動時間,咱們須要知道應用在啓動時到底執行了哪些方法或函數,經過將這些方法或函數進行重排,並放在.order
文件中並配置到項目工程,來達到加快應用啓動時間的目的.有關詳情請查看iOS啓動優化之二進制重排html
這裏有一篇文章介紹了Clang插樁的相關方案node
在項目工程的以下位置添加-fsanitize-coverage=func,trace-pc-guard
的編繹設置的標記:數組
在工程中建立一個文件,並將以下代碼copy到文件中,這裏以我本身建立的文件爲例:xcode
//
// XJHClangHookFuncTool.m
// clangDemo
//
// Created by 熊進輝 on 2020/11/22.
//
#import "XJHClangHookFuncTool.h"
#import <dlfcn.h>
#import <libkern/OSAtomic.h>
@implementation XJHClangHookFuncTool
void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
uint32_t *stop) {
static uint64_t N; // Counter for the guards.
if (start == stop || *start) return; // Initialize only once.
printf("INIT: %p %p\n", start, stop);
for (uint32_t *x = start; x < stop; x++)
*x = ++N; // Guards should start from 1.
}
//原子隊列
static OSQueueHead symbolList = OS_ATOMIC_QUEUE_INIT;
//定義符號結構體
typedef struct {
void *pc;
void *next;
}SYNode;
void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
// if (!*guard) return; // Duplicate the guard check.
/* 精肯定位 哪裏開始 到哪裏結束! 在這裏面作判斷寫條件!*/
void *PC = __builtin_return_address(0);
SYNode *node = malloc(sizeof(SYNode));
*node = (SYNode){PC,NULL};
//進入
OSAtomicEnqueue(&symbolList, node, offsetof(SYNode, next));
}
+(NSString *)getClangHookFuncsListFilePath{
NSMutableArray <NSString *> * symbolNames = [NSMutableArray array];
while (YES) {
SYNode * node = OSAtomicDequeue(&symbolList, offsetof(SYNode, next));
if (node == NULL) {
break;
}
Dl_info info;
dladdr(node->pc, &info);
NSString * name = @(info.dli_sname);
BOOL isObjc = [name hasPrefix:@"+["] || [name hasPrefix:@"-["];
NSString * symbolName = isObjc ? name: [@"_" stringByAppendingString:name];
[symbolNames addObject:symbolName];
}
//取反
NSEnumerator * emt = [symbolNames reverseObjectEnumerator];
//去重
NSMutableArray<NSString *> *funcs = [NSMutableArray arrayWithCapacity:symbolNames.count];
NSString * name;
while (name = [emt nextObject]) {
if (![funcs containsObject:name]) {
[funcs addObject:name];
}
}
//幹掉本身!
[funcs removeObject:[NSString stringWithFormat:@"%s",__FUNCTION__]];
//將數組變成字符串
NSString * funcStr = [funcs componentsJoinedByString:@"\n"];
NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"hank.order"];
NSData * fileContents = [funcStr dataUsingEncoding:NSUTF8StringEncoding];
[[NSFileManager defaultManager] createFileAtPath:filePath contents:fileContents attributes:nil];
NSLog(@"%@",funcStr);
return filePath;
}
@end
複製代碼
經過上面建立的類,你就能夠在你工程的第一個界面的viewDidLoad裏面調用getClangHookFuncsListFilePath
,從而拿到二進制重排的.order
文件了,經過在項目中配置這個文件咱們就完成了二進制重排的啓動優化了。markdown
重排後的方法打印以下: 函數
打開hank.order文件以下: oop
記得把最後一個符號刪除,它是你外部調用的位置,不須要寫進二進制重排裏面。post
若是你是用真機來調試的,那麼你要拿到對應的hank.order文件,方法以下: 打開xcode工程->Window->Devices And Simulators ->選中對應的工程 ->點擊工程列表下的「齒輪」圖標->Download Continaer,而後顯示包內容,到tmp文件夾中找到對應的hank.order文件. 優化