Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RunTime 之方法交换 #4

Open
aTreey opened this issue Jun 5, 2018 · 0 comments
Open

RunTime 之方法交换 #4

aTreey opened this issue Jun 5, 2018 · 0 comments
Labels
RunTime Extra attention is needed

Comments

@aTreey
Copy link
Owner

aTreey commented Jun 5, 2018

以前只是看到过运行时相关的资料,现在项目中依然在用UIWebView 最近打算给WebView 加一个假的进度条,所以打算通过使用RunTimeUIWebView 增加分类关联属性和方法的方式实现

方法交换

  • 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:关联策略
@aTreey aTreey added the RunTime Extra attention is needed label Jun 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RunTime Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant