以前只是看到过运行时相关的资料,现在项目中依然在用UIWebView 最近打算给WebView 加一个假的进度条,所以打算通过使用RunTime给UIWebView 增加分类关联属性和方法的方式实现
方法交换
-
class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name) 获取cls类的实例方法,
cls 要获取实例方法的相关类,
name 需要获取类的实例方法名称
-
class_getClassMethod(Class _Nullable cls, SEL _Nonnull name) 获取cls类的类方法,
cls 要获取实例方法的相关类,
name 需要获取类的类方法名称
-
method_getImplementation 获取一个方法的IMP(方法的实现),具体是指implement
-
method_getTypeEncoding 获取一个方法实现的Type字符串,包括参数类型和返回值类型
-
class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, const char * _Nullable types) 添加一个新的方法,
cls: 需要被添加的类
SEL: 要被添加的方法 例如:@selector(webViewDidFinishLoad:)
IMP: 添加的方法实现地址,例如:(IMP)my_webViewDidFinishLoad
types: 方法实现的Type字符串,包括参数类型和返回值类型
无参无返回值: "V@:"
有参无返回值: "i@:" 返回值为`int`类型
有参有返回值: "i@:@" 返回值为`int`类型,有一个参数
- 返回值为
BOOl
- 保证即便originalSelector只在父类中实现,也能达到Method Swizzling的目的, 比如一个方法只是在父类中实现而在子类中未实现,
class_addMethod就会执行返回值为YES以达到方法替换,
- 如果子类本身实现了这个方法,返回值为NO,然后我们只需要直接执行
class_replaceMethod方法就可以达到目的
-
class_replaceMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, const char * _Nullable types) 替换类中添加成功的方法的实现, 如果该方法不存在就会添加该方法, 覆盖执行class_addMethod然后再替换换两个方法实现
-
method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2) 交换两个已经存在的方法实现
交换方法代码示例参考
给分类关联属性和方法
-
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key) 给get方法关联值,返回与给定键的特定对象关联的值
-
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key, id _Nullable value, objc_AssociationPolicy policy) 给set方法关联值,
- object:要关联的源对象
- key:关联时标记是哪一个属性的key,用于区分关联的多个属性,可以用
_cmd代替, _cmd 在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例一样,每个方法都是不一样的
- value: 关联的对象
- policy:关联策略
以前只是看到过运行时相关的资料,现在项目中依然在用
UIWebView最近打算给WebView加一个假的进度条,所以打算通过使用RunTime给UIWebView增加分类关联属性和方法的方式实现方法交换
class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name)获取cls类的实例方法,cls要获取实例方法的相关类,name需要获取类的实例方法名称class_getClassMethod(Class _Nullable cls, SEL _Nonnull name)获取cls类的类方法,cls要获取实例方法的相关类,name需要获取类的类方法名称method_getImplementation获取一个方法的IMP(方法的实现),具体是指implementmethod_getTypeEncoding获取一个方法实现的Type字符串,包括参数类型和返回值类型class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, const char * _Nullable types)添加一个新的方法,cls: 需要被添加的类SEL: 要被添加的方法 例如:@selector(webViewDidFinishLoad:)IMP: 添加的方法实现地址,例如:(IMP)my_webViewDidFinishLoadtypes: 方法实现的Type字符串,包括参数类型和返回值类型BOOlclass_addMethod就会执行返回值为YES以达到方法替换,class_replaceMethod方法就可以达到目的class_replaceMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, const char * _Nullable types)替换类中添加成功的方法的实现, 如果该方法不存在就会添加该方法, 覆盖执行class_addMethod然后再替换换两个方法实现method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2)交换两个已经存在的方法实现交换方法代码示例参考
给分类关联属性和方法
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)给get方法关联值,返回与给定键的特定对象关联的值objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key, id _Nullable value, objc_AssociationPolicy policy)给set方法关联值,_cmd代替,_cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例一样,每个方法都是不一样的