您的位置:首页 > 其它

笔记:利用 runtime 交换方法、给分类动态添加属性

2018-03-16 15:41 525 查看
第一次写博客,有些小紧张,如有不对的地方还请大牛们及时指出,在此先感谢各位大牛了...

一、利用 runtime 交换方法:
1、交换方法的实现
#import "UIImage+mImage.h"

@implementation UIImage (mImage)
+(void)load{
//load 把类加载到内存时调用,只会调用一次,在这里用 runtime 交换方法,能够确保在调用方法之前交换。
//1、 获取方法的地址 class_getClassMethod(参数1->类,参数2->方法名) (获取 'get' 某个类 ‘class' 的方法 ’method‘
Method imageNamedMethod = class_getClassMethod(self, @selector(imageNamed:));
Method in_imageNamedMethod = class_getClassMethod(self, @selector(in_imageNamed:));

//2、交换方法的地址,相当于交换实现方式 method_exchangeImplementations(参数1->方法地址1,参数2->方法地址2) (方法 ’method‘ 交换 ’exchange‘ 实现方式 ’Implementations‘)
method_exchangeImplementations(imageNamedMethod, in_imageNamedMethod);

}

// 调用 imageNamed => in_imageNamed
// 调用 in_imageNamed => imageNamed
+(UIImage *)in_imageNamed:(NSString *)name{
UIImage *image = [UIImage in_imageNamed:name];
if (image) {
NSLog(@"runtime交换方法--加载成功");
}else{
NSLog(@"runtime交换方法--加载失败");
}
return image;
}
@end

2、调用#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *iamgeV;
@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
UIImage *image = [UIImage imageNamed:@"XXX"];
_iamgeV.image = image;

}3、打印
2018-03-16 12:47:43.131559+0800 2[2475:2056911] runtime交换方法--加载成功


二、给分类动态添加属性:给分类动态添加属性实质上就是将这个属性跟这个类关联起来,例如给 NSObject 添加一个分类,在分类里给 NSObject 添加一个 title 的属性,实质上就是将 title 属性跟 NSObject 类关联起来。
1、动态添加属性
#import "NSObject+Title.h"
#import <objc/message.h>
@implementation NSObject (Title)
// 在分类里是不能给类添加属性的,即使是用了 @property 也只是生成了 set 和 get 方法的声明,并没有生成带下滑线的属性以及 set、get 方法的实现。runtime 可以通过 objc_setAssociatedObject(id object->要关联的对
9294
象, const void *key->关联的属性名称, id value->关联的属性值, objc_AssociationPolicy policy->保存策略)方法将属性跟类关联起来。(设置 ‘set’ 关联 ‘associatded' 到类 ’object‘)
-(void)setTitle:(NSString *)title{
// objc_setAssociatedObject
objc_setAssociatedObject(self, @"title", title, OBJC_ASSOCIATION_COPY);

}
-(NSString *)title{
// objc_getAssociatedObject
return objc_getAssociatedObject(self, @"title");
}
@end


2、调用验证#import "ViewController.h"
#import "NSObject+Title.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// 调用
NSObject *objc = [[NSObject alloc] init];
objc.title = @"这是 runtime 动态关联的属性";
NSLog(@"runtime 动态关联属性成功,title = %@", objc.title);
}3、打印2018-03-16 14:55:20.751379+0800 2[2515:2098412] runtime 动态关联属性成功,title = 这是 runtime 动态关联的属性

注:本文参考了《iOS模式详解runtime面试工作》,用自己比较能够理解的方式做了一下笔记,在此感谢原文作者!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: