iOS启动时间优化之二进制重排笔记

获取启动到首页用到的方法符号

1.生成orderfile

各个target的other c flag (包括pod进来的)添加

-fsanitize-coverage=func,trace-pc-guard

另外对于swift项目或组件:
搜索 Other Swift Flags , 添加如下配置 :

-sanitize-coverage=func
-sanitize=undefined

然后,在需要输出orderfile的地方添加,项目中选择在首页的viewDidAppear添加

KMeetingGetOrderFileTool *tool = [[KMeetingGetOrderFileTool alloc] init];
[tool doTrigger];

KMeetingGetOrderFileTool.h文件:

#import 

NS_ASSUME_NONNULL_BEGIN

@interface KMeetingGetOrderFileTool : NSObject
- (instancetype)init;
-(void)doTrigger;
@end

KMeetingGetOrderFileTool.m文件:

NS_ASSUME_NONNULL_END
KMeetingGetOrderFileTool.m文件
#import "KMeetingGetOrderFileTool.h"

#import "dlfcn.h"
#import 

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 symboList = OS_ATOMIC_QUEUE_INIT;
static BOOL isEnd = NO;
//定义符号结构体
typedef struct{
    void * pc;
    void * next;
}SymbolNode;

void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
    //if (!*guard) return;  // Duplicate the guard check.
    if (isEnd) {
        return;
    }
    void *PC = __builtin_return_address(0);
    
    SymbolNode * node = malloc(sizeof(SymbolNode));
    *node = (SymbolNode){PC,NULL};
    
    //入队
    // offsetof 用在这里是为了入队添加下一个节点找到 前一个节点next指针的位置
    OSAtomicEnqueue(&symboList, node, offsetof(SymbolNode, next));
}



@implementation KMeetingGetOrderFileTool

- (instancetype)init
{
    self = [super init];
    if (self) {
        
    }
    return self;
}
- (void)doTrigger {
    isEnd = YES;
    NSMutableArray * symbolNames = [NSMutableArray array];
    while (true) {
        //offsetof 就是针对某个结构体找到某个属性相对这个结构体的偏移量
        SymbolNode * node = OSAtomicDequeue(&symboList, offsetof(SymbolNode, 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];
        
        //去重
        if (![symbolNames containsObject:symbolName]) {
            [symbolNames addObject:symbolName];
        }
    }

    //取反
    NSArray * symbolAry = [[symbolNames reverseObjectEnumerator] allObjects];
    NSLog(@"%@",symbolAry);
    
    //将结果写入到文件
    NSString * funcString = [symbolAry componentsJoinedByString:@"\n"];
    NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"fast.order"];
    NSData * fileContents = [funcString dataUsingEncoding:NSUTF8StringEncoding];
    BOOL result = [[NSFileManager defaultManager] createFileAtPath:filePath contents:fileContents attributes:nil];
    if (result) {
        NSLog(@"linkSymbol result %@",filePath);
    }else{
        NSLog(@"linkSymbol result文件写入出错");
    }
}
@end

2.配置orderfile

将符号文件fast.order拷贝到项目跟目录,然后在build setting中的Order File设置${SRCROOT}/fast.order

你可能感兴趣的:(iOS启动时间优化之二进制重排笔记)