XZ_iOS之Runtime使用运行时交换方法
交叉(交换)方法,在无法修改系统或者第三方框架的方式时,利用交叉方法,先执行自己的方法,再执行系统或第三方的方法
在AFNNetworking框架中也使用了这种方式,AFURLSessionManager类中
NSURLSession中AFN交换了resume/suspend方法! 当网络请求开始或者挂起的时候,能够发送通知!
使用运行时交叉方法,实现调整图像尺寸 代码实现如下:
XZViewController.m
//
交叉方法:实现调整图像尺寸
UIImageView *iv = [[UIImageView
alloc]
initWithFrame:CGRectMake(0,
0,
200,
200)];
iv.center
= self.view.center;
[self.view
addSubview:iv];
//
设置图像 - bundle
中的 jpg
在加载的时候,需要制定扩展名
iv.image
= [UIImage
imageNamed:@"商品图_03.jpg"];
// 相当于调用 iv setImage:<#(UIImage * _Nullable)#>
UIImageView+XZHack.h
#import
<UIKit/UIKit.h>
@interface UIImageView (XZHack)
//
当在其他位置调用 ’setImage‘
方法时,'自动'调用
xz_setImage: 方法
- (void)xz_setImage:(UIImage
*)image;
@end
UIImageView+XZHack.m
#import
"UIImageView+XZHack.h"
#import
<objc/runtime.h>
@implementation UIImageView (XZHack)
+ (void)load
{
// 1.获取
UIImageView 类的
实例方法 'setImage:'
Method originalMethod =
class_getClassMethod([self
class],
@selector(setImage:));
// 2.获取
UIImageView 类的
实例方法 'xz_setImage:',本身定义在分类中
Method swizzledMethod =
class_getClassMethod([self
class],
@selector(xz_setImage:));
// 3.交换方法
setImage 和 xz_setImage,交换完成之后
// 1>
调用 setImage
相当于调用了 xz_setImage
// 2>
调用 xz_setImage
相当于调用了 setImage
method_exchangeImplementations(originalMethod, swizzledMethod);
}
//
当在其他位置调用 ’setImage‘
方法时,'自动'调用
xz_setImage: 方法
- (void)xz_setImage:(UIImage
*)image {
NSLog(@"%s",__FUNCTION__);
// 1.根据
imageView的大小,重新调整 image
的大小
//
使用 ‘CG’
重新生成一张和目标尺寸相同的图片
UIGraphicsBeginImageContextWithOptions(self.bounds.size,
YES,
0);
//
绘制图像
[image
drawInRect:self.bounds];
//
取得结果
UIImage *result =
UIGraphicsGetImageFromCurrentImageContext();
//
关闭上下文
UIGraphicsEndImageContext();
//
调用系统默认的 setImage
方法
[self
xz_setImage:result];
}
@end