• 通过runtime替换系统类实现的代码(从github开源库fdstackview中摘录)


    其中部分代码为汇编;由此可见oc的runtime的灵活性和能力。此代码仅供参考


    // ----------------------------------------------------

    // Runtime injection start.
    // Assemble codes below are based on:
    // https://github.com/0xced/NSUUID/blob/master/NSUUID.m
    // ----------------------------------------------------

    #pragma mark - Runtime Injection

    __asm(
          ".section        __DATA,__objc_classrefs,regular,no_dead_strip "
    #if    TARGET_RT_64_BIT
          ".align          3 "
          "L_OBJC_CLASS_UIStackView: "
          ".quad           _OBJC_CLASS_$_UIStackView "
    #else
          ".align          2 "
          "_OBJC_CLASS_UIStackView: "
          ".long           _OBJC_CLASS_$_UIStackView "
    #endif
          ".weak_reference _OBJC_CLASS_$_UIStackView "
          );

    // Constructors are called after all classes have been loaded.
    __attribute__((constructor)) static void FDStackViewPatchEntry(void) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            @autoreleasepool {
                
                // >= iOS9.
                if (objc_getClass("UIStackView")) {
                    return;
                }
                
                Class *stackViewClassLocation = NULL;
                
    #if TARGET_CPU_ARM
                __asm("movw %0, :lower16:(_OBJC_CLASS_UIStackView-(LPC0+4)) "
                      "movt %0, :upper16:(_OBJC_CLASS_UIStackView-(LPC0+4)) "
                      "LPC0: add %0, pc" : "=r"(stackViewClassLocation));
    #elif TARGET_CPU_ARM64
                __asm("adrp %0, L_OBJC_CLASS_UIStackView@PAGE "
                      "add  %0, %0, L_OBJC_CLASS_UIStackView@PAGEOFF" : "=r"(stackViewClassLocation));
    #elif TARGET_CPU_X86_64
                __asm("leaq L_OBJC_CLASS_UIStackView(%%rip), %0" : "=r"(stackViewClassLocation));
    #elif TARGET_CPU_X86
                void *pc = NULL;
                __asm("calll L0 "
                      "L0: popl %0 "
                      "leal _OBJC_CLASS_UIStackView-L0(%0), %1" : "=r"(pc), "=r"(stackViewClassLocation));
    #else
    #error Unsupported CPU
    #endif
                
                if (stackViewClassLocation && !*stackViewClassLocation) {
                    Class class = objc_allocateClassPair(FDStackView.class, "UIStackView", 0);
                    if (class) {
                        objc_registerClassPair(class);
                        *stackViewClassLocation = class;
                    }
                }
            }
        });
    }

  • 相关阅读:
    oldboy_09_03day_test1
    oldboy_09_03day
    java消息队列
    es6语法([...arr], set/map数据结构,数组扩展,箭头函数等)
    Angular 2 Expression Changed After It Has Been Checked Exception
    jQuery之Deferred对象详解
    js面向对象:Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
    Angular 4.x 动态创建组件
    JS中this的四种用法
    typescript主键自增长
  • 原文地址:https://www.cnblogs.com/fengju/p/6173603.html
Copyright © 2020-2023  润新知