美文网首页
iOS启动优化-实用篇

iOS启动优化-实用篇

作者: 顶级蜗牛 | 来源:发表于2021-08-04 00:22 被阅读0次

    配置环境变量

    Target -> Build Setting -> Custom Complier Flags -> Other C Flags

    -fsanitize-coverage=func,trace-pc-guard
    
    image.png

    Target -> Build Setting -> Custom Complier Flags -> Other Swift Flags

    -sanitize-coverage=func
    -sanitize=undefined
    
    image.png

    添加代码

    添加到启动最早的那个 ViewController.m 即可。

    #import <dlfcn.h>
    #import <libkern/OSAtomic.h>
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    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 list = OS_ATOMIC_QUEUE_INIT;
    // 定义节点结构体
    typedef struct {
        void *pc; // 存下获取到的PC
        void *next; // 指向下一个节点
    } Node;
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        NSMutableArray *arr = [NSMutableArray array];
        while (1) {
            Node *node = OSAtomicDequeue(&list, offsetof(Node, next));
            if (node == NULL) { // 退出机制
                break;
            }
            // 获取函数信息
            Dl_info info;
            dladdr(node->pc, &info);
            NSString *sname = [NSString stringWithCString:info.dli_sname encoding:NSUTF8StringEncoding];
            
            // 处理c函数以及block前缀
            BOOL isObjc = [sname hasPrefix:@"+["] || [sname hasPrefix:@"-["];
            // c函数及block需要在开头添加下划线
            sname = isObjc ? sname : [@"_" stringByAppendingString:sname];
            
            // 去重复
            if (![arr containsObject:sname]) {
                // 入栈
                [arr insertObject:sname atIndex:0];
            }
            // 打印看看
            // printf("%s \n", info.dli_sname);
        }
        // 去掉touchBegan方法(因为启动时,不会调用它)
        [arr removeObject:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        // 将数组合成字符串
        NSString *funcStr = [arr componentsJoinedByString:@"\n"];
        // 写入文件
        NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"link.order"];
        NSLog(@"path: %@", filePath);
        NSData *fileContents = [funcStr dataUsingEncoding:NSUTF8StringEncoding];
        [[NSFileManager defaultManager] createFileAtPath:filePath contents:fileContents attributes:nil];
    }
    
    void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
       // if (!*guard) return; // guard为0会直接return,不会捕获load
       void *PC = __builtin_return_address(0);
        
    //  char PcDescr[1024];
    //  printf("guard: %p %x PC %s\n", guard, *guard, PcDescr);
        
    //    Dl_info info;
    //    dladdr(PC, &info);
    //
    //    printf("fname=%s \n fbase=%p \n sname=%s \n saddr=%p \n",
    //           info.dli_fname,
    //           info.dli_fbase,
    //           info.dli_sname,
    //           info.dli_saddr);
        
        Node *node = malloc(sizeof(Node));
        *node = (Node){PC, NULL};
        //offsetOf() 计算出列尾,OSAtomicEnqueue() 把node加入list尾巴
        OSAtomicEnqueue(&list, node, offsetof(Node, next));
    }
    @end
    

    取出 order file

    1.运行看控制台打印的路径
    2.Finder 前往路径取出 order file
    3.order file放到工程根目录下

    image.png

    配置order file

    Target -> Build Setting -> Linking -> Order File

    $(SRCROOT)/link.order
    
    image.png

    重新编译

    1.command+shift+K
    2.把上述代码删除
    3.把Other C FlagsOther Swift Flags的环境变量去掉
    3.command+B
    4.打包上线

    附上
    objc-demo
    swift-demo
    喜欢的老友star星一个,感谢老铁的666

    相关文章

      网友评论

          本文标题:iOS启动优化-实用篇

          本文链接:https://www.haomeiwen.com/subject/tqsevltx.html