美文网首页
iOS 运行时常用方法

iOS 运行时常用方法

作者: liang1030 | 来源:发表于2020-12-02 16:53 被阅读0次

    1,类转字符串

    NSString *NSStringFromClass(Class aClass)
    
    OBJC_EXPORT const char * _Nonnull
    class_getName(Class _Nullable cls)
    
    //例:
    const char *cStr = class_getName([self class]);
    //const char *转字符串
    //方式一
    NSString *str = [NSString stringWithUTF8String:cStr];
    //方式二
    NSString *str = [NSString stringWithFormat:@"%s",cStr];
    

    2,字符串转类

    //方式一:
    Class _Nullable NSClassFromString(NSString *aClassName)
    
    //方式二:
    OBJC_EXPORT Class _Nullable
    objc_getClass(const char * _Nonnull name)
    

    3,根据对象获取类

    //方式一:
    [obj class];
    
    //方式二:
    OBJC_EXPORT Class _Nullable
    object_getClass(id _Nullable obj)
    

    4,选择子(SEL)转字符串

    NSString *NSStringFromSelector(SEL aSelector)
    

    5,字符串转选择子(SEL)

    SEL NSSelectorFromString(NSString *aSelectorName)
    

    6,通过类和选择子(SEL)转方法(Method)

    OBJC_EXPORT Method _Nullable
    class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name)
    

    7,动态添加方法

    //返回YES表示添加成功,NO表示类已有该方法
    OBJC_EXPORT BOOL
    class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, 
                    const char * _Nullable types)
    

    8,交换替换

    OBJC_EXPORT IMP _Nullable
    class_replaceMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, 
                        const char * _Nullable types) 
    

    9,交换 IMP 指针

    OBJC_EXPORT void
    method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2)
    

    例:使用运行时交换方法

    + (void)hookClass:(Class)classObject fromSelector:(SEL)fromSelector toSelector:(SEL)toSelector {
        Class class = classObject;
        // 得到被替换类的实例方法
        Method fromMethod = class_getInstanceMethod(class, fromSelector);
        // 得到替换类的实例方法
        Method toMethod = class_getInstanceMethod(class, toSelector);
        
        // class_addMethod 返回成功表示被替换的方法没实现,然后会通过 class_addMethod 方法先实现;返回失败则表示被替换方法已存在,可以直接进行 IMP 指针交换
        if (class_addMethod(class, fromSelector, method_getImplementation(toMethod), method_getTypeEncoding(toMethod))) {
            // 进行方法的替换
            class_replaceMethod(class, toSelector, method_getImplementation(fromMethod), method_getTypeEncoding(fromMethod));
        }else {
            // 交换 IMP 指针
            method_exchangeImplementations(fromMethod, toMethod);
        }
    }
    

    10,动态添加属性

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    [btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
    
    objc_setAssociatedObject(btn, "btnType", "custom", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    - (void)btnClick:(id)sender {
      NSString *type = objc_getAssociatedObject(sender, "btnType");
      NSlog(@"%@",type); //custom
    }
    

    11,动态获取属性值

    OBJC_EXPORT id _Nullable
    object_getIvar(id _Nullable obj, Ivar _Nonnull ivar)
    
    //例:
    Ivar propertyIvar = class_getInstanceVariable([class_instance class], "_propertyName");
    id property = object_getIvar(class_instance, propertyIvar);
    

    12,动态设置属性值

    OBJC_EXPORT void
    object_setIvar(id _Nullable obj, Ivar _Nonnull ivar, id _Nullable value) 
    
    //例:
    Ivar propertyIvar = class_getInstanceVariable([class_instance class], "_propertyName");
    object_setIvar(class_instance, nameIvar, id);
    

    相关文章

      网友评论

          本文标题:iOS 运行时常用方法

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