zoukankan      html  css  js  c++  java
  • 第27月第25天 clang -rewrite-objc main.m

    1.clang -rewrite-objc main.m

    #import <objc/runtime.h>

     

    #import<objc/message.h>

     

    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    //为了方便查看重写的代码将name改成cjmName
    @property (nonatomic, copy) NSString *cjmName;
    @property (nonatomic, assign) NSUInteger age;
    - (void)showMyself;
    
    @end
    
    @implementation Person
    
    @synthesize cjmName = _cjmName;
    @synthesize age = _age;
    
    - (void)showMyself {
        NSLog(@"Name: %@ Age: %ld", self.cjmName, self.age);
    }
    
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            
            Person *p = [[Person alloc] init];
            
            [p setValue:@"Jiaming Chen" forKey:@"cjmName"];
            [p setValue:@22 forKey:@"age"];
            
            p.cjmName = @"CCCC";
            
            [p showMyself];
        }
        return 0;
    }

    接着使用clang -rewrite-objc main.m重写为cpp文件,查看main函数重写后的代码如下:

    int main(int argc, const char * argv[]) {
        /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
    
            Person *p = ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));
    
            ((void (*)(id, SEL, id _Nullable, NSString *))(void *)objc_msgSend)((id)p, sel_registerName("setValue:forKey:"), (id _Nullable)(NSString *)&__NSConstantStringImpl__var_folders_1f_dz4kq57d4b19s4tfmds1mysh0000gn_T_main_080287_mi_1, (NSString *)&__NSConstantStringImpl__var_folders_1f_dz4kq57d4b19s4tfmds1mysh0000gn_T_main_080287_mi_2);
            ((void (*)(id, SEL, id _Nullable, NSString *))(void *)objc_msgSend)((id)p, sel_registerName("setValue:forKey:"), (id _Nullable)((NSNumber *(*)(Class, SEL, int))(void *)objc_msgSend)(objc_getClass("NSNumber"), sel_registerName("numberWithInt:"), 22), (NSString *)&__NSConstantStringImpl__var_folders_1f_dz4kq57d4b19s4tfmds1mysh0000gn_T_main_080287_mi_3);
    
            ((void (*)(id, SEL, NSString *))(void *)objc_msgSend)((id)p, sel_registerName("setCjmName:"), (NSString *)&__NSConstantStringImpl__var_folders_1f_dz4kq57d4b19s4tfmds1mysh0000gn_T_main_080287_mi_4);
    
            ((void (*)(id, SEL))(void *)objc_msgSend)((id)p, sel_registerName("showMyself"));
        }
        return 0;
    }

    https://www.jianshu.com/p/fa941b769606

    https://www.jianshu.com/p/74369c88da5f

    2

    那这里的 AutoreleasePoolPage 是什么东西呢?其实,autoreleasepool 是没有单独的内存结构的,它是通过以 AutoreleasePoolPage 为结点的双向链表来实现的。我们打开 runtime 的源码工程,在 NSObject.mm 文件的第 438-932 行可以找到 autoreleasepool 的实现源码。通过阅读源码,我们可以知道:

    • 每一个线程的 autoreleasepool 其实就是一个指针的堆栈;

    • 每一个指针代表一个需要 release 的对象或者 POOL_SENTINEL(哨兵对象,代表一个 autoreleasepool 的边界);

    • 一个 pool token 就是这个 pool 所对应的 POOL_SENTINEL 的内存地址。当这个 pool 被 pop 的时候,所有内存地址在 pool token 之后的对象都会被 release ;

    • 这个堆栈被划分成了一个以 page 为结点的双向链表。pages 会在必要的时候动态地增加或删除;

    • Thread-local storage(线程局部存储)指向 hot page ,即最新添加的 autoreleased 对象所在的那个 

    http://www.cocoachina.com/ios/20150610/12093.html

  • 相关阅读:
    go基础第六篇:依赖管理
    go基础第五篇:并发
    go基础第四篇:error、panic、recover
    go基础第三篇:结构体、函数、方法、接口
    docker第二篇:docker compose
    docker第一篇:docker概念及基础命令
    编辑距离
    常见安全漏洞
    go基础第二篇:类型
    go基础第一篇:基本语法
  • 原文地址:https://www.cnblogs.com/javastart/p/10173471.html
Copyright © 2011-2022 走看看