美文网首页
runtime-API-class

runtime-API-class

作者: Berning | 来源:发表于2023-09-19 07:11 被阅读0次

    1.获取类名

        //1. const char * class_getName(Class cls)
        const char * className = class_getName(NSPerson.class);
        NSLog(@"class name : %s",className);
    

    2.判断是否元类

        //2.
    //    BOOL isMetaClass = class_isMetaClass(NSPerson.class);
        BOOL isMetaClass = class_isMetaClass(object_getClass(NSPerson.class));
        NSLog(@"isMetaClass : %d",isMetaClass);
    

    3.获取父类

        Class superClass = class_getSuperclass(NSPerson.class);
        NSLog(@"%@",superClass);
    

    4.设置父类(DEPRECATED)

        /**
         __OSX_DEPRECATED(10.5, 10.5, "not recommended")
         __IOS_DEPRECATED(2.0, 2.0, "not recommended")
         __TVOS_DEPRECATED(9.0, 9.0, "not recommended")
         __WATCHOS_DEPRECATED(1.0, 1.0, "not recommended")
    
         */
        
    //    class_setSuperclass(Class  _Nonnull __unsafe_unretained cls, Class  _Nonnull __unsafe_unretained newSuper)
        
    
    

    5.class version

    /**@note You can use the version number of the class definition to provide versioning of the
    interface that your class represents to other classes. This is especially useful for object
    serialization (that is, archiving of the object in a flattened form), where it is important to
    recognize changes to the layout of the instance variables in different class-definition versions.
    */
    
      class_setVersion(NSPerson.class, 1);
        
       NSLog(@"class_version : %d", class_getVersion(NSPerson.class));
    

    6.获取类的实例对象的大小

        size_t size = class_getInstanceSize(NSPerson.class);
    //    size_t size = class_getInstanceSize(object_getClass(NSPerson.class));
    
        NSLog(@"%zd",size);
    
        
    

    8.成员变量(ivar)获取

    • class_getInstanceVariable
    • class_getClassVariable
    • class_copyIvarList
        Ivar age_ivar = class_getInstanceVariable(NSPerson.class,"_age");
    
        const char * age_name = ivar_getName(age_ivar);
        const char * age_type = ivar_getTypeEncoding(age_ivar);
        NSLog(@"name:%s , type: %s",age_name ,age_type);
        
    
        Ivar isa = class_getClassVariable(NSPerson.class,"isa");
        
        const char * isa_name = ivar_getName(isa);
        const char * isa_type = ivar_getTypeEncoding(isa);
        NSLog(@"name:%s , type: %s",isa_name ,isa_type);
        
        
        //8.class_copyIvarList
        unsigned int outCount = 0;
        Ivar *ivars = class_copyIvarList(NSPerson.class, &outCount);
        for (int i = 0; i < outCount; i++) {
            const char *name = ivar_getName(ivars[i]);
            NSLog(@"%s",name);
        }
        free(ivars);
      
    

    9.方法(method)的获取

    • class_getInstanceMethod
    • class_getClassMethod
    • class_getMethodImplementation
    • class_respondsToSelector
    • class_copyMethodList
        Method method = class_getInstanceMethod(NSPerson.class, sel_registerName("run"));
        NSLog(@"%@",NSStringFromSelector(method_getName(method)));
        NSLog(@"%s",method_getTypeEncoding(method));
        NSLog(@"%p",method_getImplementation(method));
        
        Method clsMethod = class_getClassMethod(NSPerson.class, @selector(person));
        NSLog(@"%@",NSStringFromSelector(method_getName(clsMethod)));
        NSLog(@"%s",method_getTypeEncoding(clsMethod));
        NSLog(@"%p",method_getImplementation(clsMethod));
        
        
        IMP runIMP = class_getMethodImplementation(NSPerson.class, @selector(run));
        NSLog(@"%p",runIMP);
        
    //    OBJC_ARM64_UNAVAILABLE
    //    class_getMethodImplementation_stret(Class  _Nullable __unsafe_unretained cls, SEL  _Nonnull name)
    
    //    区别都调用class_respondsToSelector_inst(id inst, SEL sel, Class cls),
        //inst 传nil
        BOOL isRun = class_respondsToSelector(NSPerson.class, @selector(run));
        NSLog(@"isRun:%d",isRun);
        
        //inst传self
        BOOL isR = [NSPerson.new respondsToSelector:@selector(run)];
        NSLog(@"isR:%d",isR);
       
        //12.class_copyMethodList
        unsigned int methodCount = 0;
        Method *methods = class_copyMethodList(object_getClass(NSPerson.class), &methodCount);
        for (int i = 0; i < methodCount; i++) {
            SEL mname = method_getName(*(methods + i));
            NSLog(@"+m%d:%@",i,NSStringFromSelector(mname));
        }
        free(methods);
        
        methods = class_copyMethodList(NSPerson.class, &methodCount);
        for (int i = 0; i < methodCount; i++) {
            SEL mname = method_getName(*(methods + i));
            NSLog(@"-m%d:%@",i,NSStringFromSelector(mname));
        }
        free(methods);
    
    

    pragma mark - protocol

    10.协议(protocol)的获取

    • class_conformsToProtocol
    • class_copyProtocolList
        BOOL isConformProtocol = class_conformsToProtocol(NSPerson.class,@protocol(NSPersonDelegate));
        
        //conformsToProtocol:遍历一个实例的类及其类的superclass然后 调用了class_conformsToProtocol,
    //    BOOL isConformProtocol = [NSPerson.new conformsToProtocol:@protocol(NSPersonDelegate)];
        NSLog(@"isConformProtocol:%d",isConformProtocol);
        NSString *persond = NSStringFromProtocol(@protocol(NSPersonDelegate));
        NSLog(@"persond:%@",persond);
        
        
     unsigned int protocolCount = 0;
        Protocol * __unsafe_unretained * protocols = class_copyProtocolList(NSPerson.class, &protocolCount);
        
        for (int i = 0; i < protocolCount; i++) {
            NSLog(@"prtocol%i:%s",i,protocol_getName(*(protocols + i)));
        }
        free(protocols);
        
    

    11.属性的获取

    • class_getProperty
    • class_copyPropertyList
        //T@"NSString",R,C,N,GgetName,V_name
        objc_property_t age_property = class_getProperty(NSPerson.class, "name");
        NSLog(@"%s,attr:%s",property_getName(age_property),property_getAttributes(age_property));
        
        unsigned int property_count = 0;
        objc_property_t *properties = class_copyPropertyList(NSPerson.class, &property_count);
        for (int i = 0; i < property_count; i++) {
            NSLog(@"property%i:%s",i,property_getName(*(properties + i)));
        }
        free(properties);
        
    
    

    12.成员变量布局

    • class_getIvarLayout
    • class_getWeakIvarLayout
        
    
        const  uint8_t *ivar_layout = class_getIvarLayout(NSPerson.class);
        NSLog(@"ivar_layout:%s",ivar_layout);
    
        if(ivar_layout != NULL)
        {
            int i = 0;
            uint8_t value_s = ivar_layout[i];
            while (value_s != 0x0) {
                printf("ivar_layout:\\x%02x\n", value_s);
                value_s = ivar_layout[++i];
            }
        }
        
        const uint8_t *ivar_weak_layout = class_getWeakIvarLayout(NSPerson.class);
    
        if(ivar_weak_layout != NULL)
        {
            int i = 0;
            uint8_t value_s = ivar_weak_layout[i];
            while (value_s != 0x0) {
                printf("ivar_weak_layout:\\x%02x\n", value_s);
                value_s = ivar_weak_layout[++i];
            }
    
        }
    

    12.向类中添加成员变量/方法/协议/属性

        //12.1.1.method add
        BOOL isAdd = class_addMethod(NSPerson.class, @selector(travel), (IMP)travel_add, "v@0:8");
        NSLog(@"isAdd:%d",isAdd);
        
        [NSPerson.new travel];
    //    [NSPerson.new performSelector:@selector(travel)];
        
        
        NSLog(@"eatIMP1:%p",class_getMethodImplementation(NSPerson.class, @selector(eat)));
        
        //12.1.2.method replace
        //返回替换前方法的地址
        IMP methodIMP = class_replaceMethod(NSPerson.class, @selector(eat), (IMP)eat_replace,
                            "v@0:8");
        NSLog(@"eatIMP2:%p",class_getMethodImplementation(NSPerson.class, @selector(eat)));
    
        NSLog(@"methodIMP:%p",methodIMP);
        
        [NSPerson.new eat];
        
        //12.2.ivar
        Class NSCat = objc_allocateClassPair(NSObject.class, "NSCat", 0);
        
        BOOL isAddIvar = class_addIvar(NSCat, "_name", 8, 1<<0, @encode(NSString *));
        
        NSLog(@"isAddIvar:%d",isAddIvar);
        objc_registerClassPair(NSCat);
        
        
        //12.3.protocol
        BOOL is_add_protocol = class_addProtocol(NSPerson.class, @protocol(NSCopying));
        NSLog(@"is_add_protocol%d",is_add_protocol);
        
        //12.4.1.property add
        
        objc_property_attribute_t types = { "T", "@\"NSString\"" };
    
        objc_property_attribute_t ownership = {"C", ""}; // C = copy
    //    objc_property_attribute_t ownership = {"&", ""}; // & = strong/retain
    
        objc_property_attribute_t atomic = {"N", ""}; // N = nonatomic
    
        objc_property_attribute_t rw = {"R", ""}; // R = readonly
    
        objc_property_attribute_t backIvar = {"V","_car"};
    
        objc_property_attribute_t attrs[] = { atomic,rw,types, ownership, backIvar };
    
    
        BOOL is_add_property = class_addProperty(NSPerson.class, "car", attrs, 5);
        
        NSLog(@"is_add_property:%d",is_add_property);
        
        //12.4.2.property replace
        objc_property_attribute_t age_t = {"T","@\"NSString\""};
        objc_property_attribute_t age_owner = {"C",""};
        objc_property_attribute_t age_atomic = {"N",""};
        objc_property_attribute_t age_rw = {"R",""};
        objc_property_attribute_t age_i = {"V","__age"};
        objc_property_attribute_t age_attr[] = {age_t,age_rw,age_owner,age_atomic,age_i};
        
        class_replaceProperty(NSPerson.class, "age", age_attr, 5);
        
    //    unsigned int property_count = 0;
    //    objc_property_t *properties = class_copyPropertyList(NSPerson.class, &property_count);
    //    for (int i = 0; i < property_count; i++) {
    //        NSLog(@"property%i:%s,%s",i,property_getName(*(properties + i)),property_getAttributes(*(properties + i)));
    //    }
    //    free(properties);
    
    

    13.成员变量布局设置

    #warning to learn
    
    //    class_setIvarLayout(NSPerson.class, <#const uint8_t * _Nullable layout#>);
    //    class_setWeakIvarLayout(NSPerson.class, <#const uint8_t * _Nullable layout#>)
    

    14.创建实例

        NSPerson *person_0 = class_createInstance(NSPerson.class, 0);
        [person_0 travel];
        [person_0 run];
        [person_0 eat];
    

    15.获取镜像(framework / dynamic library)

        const char * image = class_getImageName(NSPerson.class);
        NSLog(@"image:%s",image);
    

    相关文章

      网友评论

          本文标题:runtime-API-class

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