美文网首页
iOS-黑魔法

iOS-黑魔法

作者: JerrySi | 来源:发表于2020-06-08 10:35 被阅读0次

    最近项目中一直用到OC的代码,有必要把常用的当时平常又不是很在意的黑魔法再列举下。

    attribute((cleanup))

    用于修饰一个变量,在它的作用域结束时可以自动执行一个指定的方法

    static void blockCleanUp(__strong void(^*block)(void)) {
        (*block)();
    }
    #define onExit \
        __strong void(^block)(void) __attribute__((cleanup(blockCleanUp), unused)) = ^
    
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        onExit {
           NSLog(@"2");
        };
        NSLog(@"1");
    }
    

    used

    used的作用是告诉编译器,我声明的这个符号是需要保留的。被used修饰以后,意味着即使函数没有被引用,在Release下也不会被优化。如果不加这个修饰,那么Release环境链接器会去掉没有被引用的段。
    冷启动优化:Clang 提供了很多的编译器函数,它们可以完成不同的功能。其中一种就是 section() 函数,section()函数提供了二进制段的读写能力,它可以将一些编译期就可以确定的常量写入数据段。 在具体的实现中,主要分为编译期和运行时两个部分。在编译期,编译器会将标记了 attribute((section())) 的数据写到指定的数据段中,例如写一个{key(key代表不同的启动阶段), *pointer}对到数据段。到运行时,在合适的时间节点,在根据key读取出函数指针,完成函数的调用。

    #define RAM_FUNCTIONNAME_EXPORT __attribute__((used, section("__RAM, __funcName"))) \
    static const char *__ram_funcName__ = __func__
    
    #pragma mark - 实现存储字符串
    struct RAM_String {
        __unsafe_unretained NSObject *key;
        __unsafe_unretained NSObject *value;
    };
    /// id 参数,在同一个.m文件中调用此宏需要id唯一
    #define RAM_STRINGS_EXPORT(key, value, id) __attribute__((used, section("__RAM,__ram.data"))) \
    static const struct RAM_String __S##id= (struct RAM_String){key, value};
    
    #pragma mark - 实现存储block
    struct RAM_Block {
        char *key;
        __unsafe_unretained void (^block)(void);
    };
    
    #define RAM_BLOCKS_EXPORT(key, block) __attribute__((used, section("__RAM," "__"#key ".block"))) \
    static const struct RAM_Block __B##key = (struct RAM_Block){((char *)&#key), block};
    
    #pragma mark - 实现存储方法
    struct RAM_Function {
        char *key;
        void (*function)(void);
    };
    
    #define RAM_FUNCTION_EXPORT(key) \
    static void _ram##key(void); \
    __attribute__((used, section("__RAM," "__"#key ".func"))) \
    static const struct RAM_Function __F##key = (struct RAM_Function){(char *)(&#key), (void *)(&_ram##key)}; \
    static void _ram##key \
    

    参考:https://www.jianshu.com/p/33663906f7a2

    objc_runtime_name

    用于 @interface 或 @protocol,将类或协议的名字在编译时指定成另一个,这个属性可以用来做代码混淆

     __attribute__((objc_runtime_name("OtherTest")))
     @interface Test : NSObject
     @end
     
     NSLog(@"%@", NSStringFromClass([Test class])); // "OtherTest"
    

    相关文章

      网友评论

          本文标题:iOS-黑魔法

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