【iOS】Objective-C Runtime里面的一些方法

 

Apple Runtime

    //获取类名
    const char *name = class_getName([self class]);
    NSString *nameStr = [[NSString alloc] initWithUTF8String:name];
    NSLog(@"nameStr--->%@",nameStr);
    
    //获取父类名
    Class superClass = class_getSuperclass([self class]);
    NSString *superNameStr = NSStringFromClass(superClass);
    NSLog(@"superNameStr--->%@",superNameStr);
    
    //判断类对象是否是元类
    BOOL isMetaClass = class_isMetaClass([self class]);
    NSLog(@"isMetaClass--->%d",isMetaClass);
    
    //获取类对象的大小
    size_t size = class_getInstanceSize([self class]);
    NSLog(@"size--->%td",size);
    
    //成员变量都是带下划线的
    Ivar ivar = class_getInstanceVariable([self class], [@"_desc" UTF8String]);
    NSString *descValue = object_getIvar(self, ivar);
    NSLog(@"descValue--->%@,%s,%s,%td",descValue,ivar_getName(ivar),ivar_getTypeEncoding(ivar),ivar_getOffset(ivar));
    
    //⚠️不能在已存在的class中添加Ivar,所有说必须通过objc_allocateClassPair动态创建一个class,才能调用class_addIvar创建Ivar,最后通过objc_registerClassPair注册class。
    BOOL addIvarSuccess =  class_addIvar([self class], [@"shool" UTF8String], sizeof(id), log2(sizeof(id)), "@");
    if (addIvarSuccess) {NSLog(@"addIvarSuccess");} //返回NO
    
    //获取成员变量列表
    unsigned int count;
    Ivar *ivalList =  class_copyIvarList([self class], &count);
    NSMutableArray *ivars = [@[] mutableCopy];
    if (count > 0)
    {
        for (int i=0; i<count; i++)
        {
            Ivar ivar = ivalList[i];
            const char *cname = ivar_getName(ivar);
            NSString *name = [[NSString alloc] initWithUTF8String:cname];
            [ivars addObject:name];
        }
    }
    
    free(ivalList);
    
    //\x02  copy被当成是strong来记录
    const uint8_t *layout = class_getIvarLayout([self class]);
    
    //⚠️ objc_registerClassPair 调用之前才能修改 Ivar Layout
    class_setIvarLayout([self class], layout);

    //获取指定的属性
    objc_property_t pt = class_getProperty([self class], "desc");
    
    //获取属性列表
    unsigned int cout;
    objc_property_t *propertys = class_copyPropertyList([self class], &cout);
    for (int i=0; i<cout; i++) {
        objc_property_t property = propertys[i];
        NSString *perpertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
        id propertyValue  = [self valueForKey:(NSString *)perpertyName];
        NSLog(@"%@ %@", perpertyName, propertyValue);
    }
    
    free(propertys);
    
    //为类添加新的方法
    SEL sel = NSSelectorFromString(@"gohome");
    IMP imp = class_getMethodImplementation([self class], sel);
    
    //v表示void表示没有返回值
    //@表示id,也就是要添加方法的类
    //:表示添加方法的类型
    //@表示参数的类型
    
    bool rest = class_addMethod([self class], sel, imp, "v@:");
    NSLog(@"添加方法gohome:%d",rest);
    
    //方法的替换
    SEL willReplaceSel = @selector(willGohome:);
    IMP willReplaceImp = class_getMethodImplementation([self class], willReplaceSel);
    
    IMP im = class_replaceMethod([self class], willReplaceSel, willReplaceImp, @"v@:@");
    
    //方法的交换,一般写在类的+(void)load方法里
    Method method1 = class_getInstanceMethod([self class], @selector(eat));
    Method method2 = class_getInstanceMethod([self class], @selector(antherEat));
    method_exchangeImplementations(method1, method2);
    
    //class_getMethodImplementation和class_getMethodImplementation_stret之间的区别
    //http://www.voidcn.com/article/p-gytqoqsv-bvs.html
    
    //判断某个类是否有实例方法
    BOOL have =  class_respondsToSelector([self class], @selector(viewDidLoad));
    NSLog(@"have:%d",have);
    
    //添加协议
    class_addProtocol([self class], objc_getProtocol("NSCoding"));
    class_addProtocol([self class], NSProtocolFromString(@"NSCoding"));

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值