Skip to content

Commit

Permalink
【ADD】NSString+LYUnits添加获取文件大小功能【ADD】UIDevice+LYHardware添加获取运营商功能【ADD】…
Browse files Browse the repository at this point in the history
…NSObject+LYHook添加通过blockf重写方法的功能
  • Loading branch information
吴浪 committed Dec 17, 2018
1 parent 2ab2375 commit a889d39
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
### [0.3.0]
-【ADD】'NSString+LYUnits'添加获取文件大小功能
-【ADD】'UIDevice+LYHardware'添加获取运营商功能
-【ADD】'NSObject+LYHook'添加通过blockf重写方法的功能
29 changes: 27 additions & 2 deletions Example/LYToolsKit/LYViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

#import "LYViewController.h"
#import <LYToolsKit/LYToolsKit.h>
#import <objc/runtime.h>

typedef void(^Blick)(void);

@interface LYViewController ()

Expand All @@ -25,14 +28,36 @@ - (void)viewDidLoad
LYHyperlinksButton *btn1 = [LYHyperlinksButton ly_ViewWithColor:[UIColor redColor]];
[btn1 setTitle:@"啧啧啧" forState:UIControlStateNormal];
btn1.frame = CGRectMake(50, 100, 50, 50);

[self.view addSubview:btn1];

[self.class ly_OverrideImplement:@selector(setName:) block:^id _Nonnull(Class _Nonnull __unsafe_unretained originClass, SEL _Nonnull originSEL, IMP _Nonnull originIMP) {
return ^(id obj, NSString *name) {

};
}];

// [self ly_hookOrigMethod:@selector(btnClick) newMethod:meth];
// [self ly_hookOrigMethod:@selector(btnClick) newMethod:@selector(my_btnClick1:)];

}

- (void)btnClick {

[self.class setName:@"测试"];
}

+ (void)setName:(NSString *)name {
// [LYHyperlinksButton ]
}

- (void)my_btnClick:(id)btn {
[self my_btnClick:btn];
}

- (void)my_btnClick1:(id)btn {
[self my_btnClick1:btn];
}


- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
Expand Down
18 changes: 18 additions & 0 deletions LYToolsKit/Foundation/NSObject/NSObject+LYHook.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,24 @@ NS_ASSUME_NONNULL_BEGIN

@interface NSObject (LYHook)

/**
block重写方式实现
void(*)(id, SEL, ...)
id(*)(id, SEL, ...)
@param targetSEL 目标方法选择器
@param block 该 block 必须返回一个 block,返回的 block 将被当成 targetSEL 的新实现
@return 是否重写成功
*/
+ (BOOL)ly_OverrideImplement:(SEL)targetSEL block:(id(^)(Class originClass, SEL originSEL, IMP originIMP))block;
/**
block重写方式实现
void(*)(id, SEL, ...)
id(*)(id, SEL, ...)
@param targetSEL 目标方法选择器
@param block 该 block 必须返回一个 block,返回的 block 将被当成 targetSEL 的新实现
@return 是否重写成功
*/
- (BOOL)ly_OverrideImplement:(SEL)targetSEL block:(id(^)(Class originClass, SEL originSEL, IMP originIMP))block;
/**
hook类方法的实现
Expand Down
30 changes: 30 additions & 0 deletions LYToolsKit/Foundation/NSObject/NSObject+LYHook.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,36 @@

@implementation NSObject (LYHook)

/**
* 用 block 重写某个 class 的指定方法
* @param targetClass 要重写的 class
* @param targetSelector 要重写的 class 里的实例方法,注意如果该方法不存在于 targetClass 里,则什么都不做
* @param implementBlock 该 block 必须返回一个 block,返回的 block 将被当成 targetSelector 的新实现,所以要在内部自己处理对 super 的调用,以及对当前调用方法的 self 的 class 的保护判断(因为如果 targetClass 的 targetSelector 是继承自父类的,targetClass 内部并没有重写这个方法,则我们这个函数最终重写的其实是父类的 targetSelector,所以会产生预期之外的 class 的影响,例如 targetClass 传进来 UIButton.class,则最终可能会影响到 UIView.class),implementationBlock 的参数里第一个为你要修改的 class,也即等同于 targetClass,第二个参数为你要修改的 selector,也即等同于 targetSelector,第三个参数是 targetSelector 原本的实现,由于 IMP 可以直接当成 C 函数调用,所以可利用它来实现“调用 super”的效果,但由于 targetSelector 的参数个数、参数类型、返回值类型,都会影响 IMP 的调用写法,所以这个调用只能由业务自己写。
*/
CG_INLINE BOOL OverrideImplement(Class targetClass, SEL targetSelector, BOOL isClassMethod, id(^implementBlock)(Class originClass, SEL originSEL, IMP originIMP)) {
Method originMethod;
if (isClassMethod) {
originMethod = class_getClassMethod(targetClass, targetSelector);
} else {
originMethod = class_getInstanceMethod(targetClass, targetSelector);
}
if (!originMethod || !implementBlock) {
return NO;
}
IMP originIMP = method_getImplementation(originMethod);
method_setImplementation(originMethod, imp_implementationWithBlock(implementBlock(targetClass, targetSelector, originIMP)));
return YES;
}

+ (BOOL)ly_OverrideImplement:(SEL)targetSEL block:(id _Nonnull (^)(Class _Nonnull __unsafe_unretained, SEL _Nonnull, IMP _Nonnull))block {
return OverrideImplement(self, targetSEL, YES, block);
}

- (BOOL)ly_OverrideImplement:(SEL)targetSEL block:(id _Nonnull (^)(Class _Nonnull __unsafe_unretained, SEL _Nonnull, IMP _Nonnull))block {
return OverrideImplement(self.class, targetSEL, NO, block);
}


+ (BOOL)ly_hookOrigMethod:(SEL)origSEL newMethod:(SEL)newSEL {
Method originalMethod = class_getClassMethod(self, origSEL);
Method swizzledMethod = class_getClassMethod(self, newSEL);
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

## 功能
```工具组件
方法交互,时间处理,JS脚本,KB-MB-GB转换,URL解析,URL参数拼接,URL编码,Alert弹框,设备信息,网络信息,操作轴迹,View快捷构建,图片压缩,图片放缩,倒计时,蒙版
时间处理,JS脚本,KB-MB-GB转换,URL解析,URL参数拼接,URL编码,Alert弹框,设备信息,网络信息,操作轴迹,View快捷构建,图片压缩,图片放缩,倒计时,hook方法
```

## 说明
Expand Down

0 comments on commit a889d39

Please sign in to comment.