iOS 运行时常用方法

2020-12-02  本文已影响0人  liang1030

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);
上一篇下一篇

猜你喜欢

热点阅读